head 1.28; access; symbols PTH_2_0_7:1.27 PTH_2_0_6:1.26 PTH_2_0_5:1.26 PTH_2_0_4:1.26 PTH_2_0_3:1.25 PTH_2_0_2:1.25 PTH_2_0_1:1.25 PTH_2_0_0:1.24 PTH_2_0b2:1.23 PTH_2_0b1:1.23 PTH_2_0b0:1.23 PTH_1_4:1.21.0.2 PTH_1_4_1:1.21 PTH_1_4_0:1.20 PTH_1_3_7:1.18 PTH_1_4a3:1.19 PTH_1_3_6:1.18 PTH_1_4a2:1.19 PTH_1_3_5:1.18 PTH_1_4a1:1.19 PTH_1_3_4:1.18 PTH_1_3:1.18.0.2 PTH_1_3_3:1.18 PTH_1_3_2:1.18 PTH_1_3_1:1.18 PTH_1_3_0:1.18 PTH_1_3b3:1.18 PTH_1_2_3:1.15.2.1 PTH_1_3b2:1.18 PTH_1_3b1:1.18 PTH_1_3a5:1.18 PTH_1_3a4:1.18 PTH_1_3a3:1.18 PTH_1_2_2:1.15.2.1 PTH_1_3a2:1.18 PTH_1_2_1:1.15.2.1 PTH_1_3a1:1.16 PTH_1_2:1.15.0.2 PTH_1_2_0:1.15 PTH_1_2b8:1.14 PTH_1_2b7:1.14 PTH_1_1_6:1.13 PTH_1_2b6:1.14 PTH_1_2b5:1.14 PTH_1_2b4:1.14 PTH_1_2b3:1.14 PTH_1_2b2:1.13 PTH_1_2b1:1.13 PTH_1_1_5:1.13 PTH_1_0_6:1.10.2.1 PTH_1_0_5:1.10.2.1 PTH_1_0:1.10.0.2 PTH_1_1:1.13.0.2 PTH_1_1_4:1.13 PTH_1_1_3:1.12 PTH_1_1_2:1.12 PTH_1_1_1:1.12 PTH_1_1_0:1.12 PTH_1_1b7:1.11 PTH_1_1b6:1.11 PTH_1_1b5:1.11 PTH_1_1b4:1.11 PTH_1_1b3:1.11 PTH_1_1b2:1.11 PTH_1_1b1:1.10 PTH_1_0_4:1.10 PTH_1_0_3:1.10 PTH_1_0_2:1.10 PTH_1_0_1:1.10 PTH_1_0_0:1.10 PTH_1_0b8:1.10 PTH_1_0b7:1.10 PTH_1_0b6:1.10 PTH_1_0b5:1.10 PTH_1_0b4:1.10 PTH_1_0b3:1.8 PTH_1_0b2:1.8 PTH_1_0b1:1.7 PTH_0_9_21:1.7 PTH_0_9_20:1.7 PTH_0_9_19:1.7 PTH_0_9_18:1.7 PTH_0_9_17:1.7 PTH_0_9_16:1.7 PTH_0_9_15:1.7 PTH_0_9_14:1.7 PTH_0_9_13:1.7 PTH_0_9_12:1.6 PTH_0_9_11:1.5 PTH_0_9_10:1.5 PTH_0_9_9:1.4 PTH_0_9_8:1.3 PTH_0_9_7:1.2 PTH_0_9_6:1.2 PTH_0_9_5:1.1 PTH_0_9_4:1.1; locks; strict; comment @ * @; 1.28 date 2007.01.01.18.23.53; author rse; state Exp; branches; next 1.27; commitid 9DhdiirNzQPBIP0s; 1.27 date 2006.06.08.17.54.53; author rse; state Exp; branches; next 1.26; commitid x8N3mLVdQgkbdeAr; 1.26 date 2004.12.31.19.34.45; author rse; state Exp; branches; next 1.25; 1.25 date 2004.07.13.10.50.49; author rse; state Exp; branches; next 1.24; 1.24 date 2003.01.01.15.49.12; author rse; state Exp; branches; next 1.23; 1.23 date 2002.10.24.15.21.14; author rse; state Exp; branches; next 1.22; 1.22 date 2002.10.15.20.34.23; author rse; state Exp; branches; next 1.21; 1.21 date 2002.01.27.11.03.41; author rse; state Exp; branches; next 1.20; 1.20 date 2001.03.24.14.51.04; author rse; state Exp; branches; next 1.19; 1.19 date 2000.03.12.16.43.16; author rse; state Exp; branches; next 1.18; 1.18 date 99.12.30.21.59.00; author rse; state Exp; branches; next 1.17; 1.17 date 99.11.09.08.11.31; author rse; state Exp; branches; next 1.16; 1.16 date 99.11.01.10.27.19; author rse; state Exp; branches; next 1.15; 1.15 date 99.10.31.11.46.13; author rse; state Exp; branches 1.15.2.1; next 1.14; 1.14 date 99.09.17.08.01.55; author rse; state Exp; branches; next 1.13; 1.13 date 99.08.28.14.30.30; author rse; state Exp; branches; next 1.12; 1.12 date 99.08.19.15.08.53; author rse; state Exp; branches; next 1.11; 1.11 date 99.08.10.07.41.35; author rse; state Exp; branches; next 1.10; 1.10 date 99.07.08.10.34.01; author rse; state Exp; branches 1.10.2.1; next 1.9; 1.9 date 99.07.08.10.19.11; author rse; state Exp; branches; next 1.8; 1.8 date 99.07.04.12.05.35; author rse; state Exp; branches; next 1.7; 1.7 date 99.06.01.09.55.26; author rse; state Exp; branches; next 1.6; 1.6 date 99.05.30.13.08.37; author rse; state Exp; branches; next 1.5; 1.5 date 99.05.28.09.05.12; author rse; state Exp; branches; next 1.4; 1.4 date 99.05.25.15.46.06; author rse; state Exp; branches; next 1.3; 1.3 date 99.05.24.07.58.13; author rse; state Exp; branches; next 1.2; 1.2 date 99.05.22.14.37.53; author rse; state Exp; branches; next 1.1; 1.1 date 99.05.21.09.44.10; author rse; state Exp; branches; next ; 1.15.2.1 date 99.11.01.10.25.01; author rse; state Exp; branches; next ; 1.10.2.1 date 99.08.31.08.30.29; author rse; state Exp; branches; next ; desc @@ 1.28 log @Adjusted all copyright messages for new year 2007. @ text @/* ** GNU Pth - The GNU Portable Threads ** Copyright (c) 1999-2007 Ralf S. Engelschall ** ** This file is part of GNU Pth, a non-preemptive thread scheduling ** library which can be found at http://www.gnu.org/software/pth/. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public ** License as published by the Free Software Foundation; either ** version 2.1 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ** USA, or contact Ralf S. Engelschall . ** ** pth_ring.c: Pth ring data structure */ /* ``Unix was not designed to stop people from doing stupid things, because that would also stop them from doing clever things.'' --Doug Gwyn */ /* * This is a "ring" data structure, a special case of a list. It is * implemented through double-chained nodes. The link structure is part * of the nodes, i.e. no extra memory is required for the ring itself * and the ring can contain as many nodes as fit into memory. The main * advantage of using a ring instead of a plain list is to make the ring * operations easier (less special cases!). The ring is usually used * in Pth to represent a "set" of something. All operations are O(1), * except for the check whether a node is part of the ring (which is * O(N)). */ #include "pth_p.h" /* initialize ring; O(1) */ intern void pth_ring_init(pth_ring_t *r) { if (r == NULL) return; r->r_hook = NULL; r->r_nodes = 0; return; } /* return number of nodes in ring; O(1) */ #if cpp #define pth_ring_elements(r) \ ((r) == NULL ? (-1) : (r)->r_nodes) #endif /* return first node in ring; O(1) */ #if cpp #define pth_ring_first(r) \ ((r) == NULL ? NULL : (r)->r_hook) #endif /* return last node in ring; O(1) */ #if cpp #define pth_ring_last(r) \ ((r) == NULL ? NULL : ((r)->r_hook == NULL ? NULL : (r)->r_hook->rn_prev)) #endif /* walk to next node in ring; O(1) */ #if cpp #define pth_ring_next(r, rn) \ (((r) == NULL || (rn) == NULL) ? NULL : ((rn)->rn_next == (r)->r_hook ? NULL : (rn)->rn_next)) #endif /* walk to previous node in ring; O(1) */ #if cpp #define pth_ring_prev(r, rn) \ (((r) == NULL || (rn) == NULL) ? NULL : ((rn)->rn_prev == (r)->r_hook->rn_prev ? NULL : (rn)->rn_prev)) #endif /* insert node into ring; O(1) */ #if cpp #define pth_ring_insert(r, rn) \ pth_ring_append((r), (rn)) #endif /* insert node after a second node in ring; O(1) */ intern void pth_ring_insert_after(pth_ring_t *r, pth_ringnode_t *rn1, pth_ringnode_t *rn2) { if (r == NULL || rn1 == NULL || rn2 == NULL) return; rn2->rn_prev = rn1; rn2->rn_next = rn1->rn_next; rn2->rn_prev->rn_next = rn2; rn2->rn_next->rn_prev = rn2; r->r_nodes++; return; } /* insert node before a second node in ring; O(1) */ intern void pth_ring_insert_before(pth_ring_t *r, pth_ringnode_t *rn1, pth_ringnode_t *rn2) { if (r == NULL || rn1 == NULL || rn2 == NULL) return; rn2->rn_next = rn1; rn2->rn_prev = rn1->rn_prev; rn2->rn_prev->rn_next = rn2; rn2->rn_next->rn_prev = rn2; r->r_nodes++; return; } /* delete an node from ring; O(1) */ intern void pth_ring_delete(pth_ring_t *r, pth_ringnode_t *rn) { if (r == NULL || rn == NULL) return; if (r->r_hook == rn && rn->rn_prev == rn && rn->rn_next == rn) r->r_hook = NULL; else { if (r->r_hook == rn) r->r_hook = rn->rn_next; rn->rn_prev->rn_next = rn->rn_next; rn->rn_next->rn_prev = rn->rn_prev; } r->r_nodes--; return; } /* prepend an node to ring; O(1) */ intern void pth_ring_prepend(pth_ring_t *r, pth_ringnode_t *rn) { if (r == NULL || rn == NULL) return; if (r->r_hook == NULL) { r->r_hook = rn; rn->rn_next = rn; rn->rn_prev = rn; } else { rn->rn_next = r->r_hook; rn->rn_prev = r->r_hook->rn_prev; rn->rn_next->rn_prev = rn; rn->rn_prev->rn_next = rn; r->r_hook = rn; } r->r_nodes++; return; } /* append an node to ring; O(1) */ intern void pth_ring_append(pth_ring_t *r, pth_ringnode_t *rn) { if (r == NULL || rn == NULL) return; if (r->r_hook == NULL) { r->r_hook = rn; rn->rn_next = rn; rn->rn_prev = rn; } else { rn->rn_next = r->r_hook; rn->rn_prev = r->r_hook->rn_prev; rn->rn_next->rn_prev = rn; rn->rn_prev->rn_next = rn; } r->r_nodes++; return; } /* treat ring as stack: push node onto stack; O(1) */ #if cpp #define pth_ring_push(r, rn) \ pth_ring_prepend((r), (rn)) #endif /* treat ring as stack: pop node from stack; O(1) */ intern pth_ringnode_t *pth_ring_pop(pth_ring_t *r) { pth_ringnode_t *rn; rn = pth_ring_first(r); if (rn != NULL) pth_ring_delete(r, rn); return rn; } /* treat ring as queue: favorite a node in the ring; O(1) */ intern int pth_ring_favorite(pth_ring_t *r, pth_ringnode_t *rn) { if (r == NULL) return FALSE; if (r->r_hook == NULL) return FALSE; /* element is perhaps already at ring hook */ if (r->r_hook == rn) return TRUE; /* move to hook of ring */ pth_ring_delete(r, rn); pth_ring_prepend(r, rn); return TRUE; } /* treat ring as queue: enqueue node; O(1) */ #if cpp #define pth_ring_enqueue(r, rn) \ pth_ring_prepend((r), (rn)) #endif /* treat ring as queue: dequeue node; O(1) */ intern pth_ringnode_t *pth_ring_dequeue(pth_ring_t *r) { pth_ringnode_t *rn; rn = pth_ring_last(r); if (rn != NULL) pth_ring_delete(r, rn); return rn; } /* check whether node is contained in ring; O(n) */ intern int pth_ring_contains(pth_ring_t *r, pth_ringnode_t *rns) { pth_ringnode_t *rn; int rc; if (r == NULL || rns == NULL) return pth_error(FALSE, EINVAL); rc = FALSE; rn = r->r_hook; if (rn != NULL) { do { if (rn == rns) { rc = TRUE; break; } rn = rn->rn_next; } while (rn != r->r_hook); } return rc; } @ 1.27 log @Adjusted all copyright messages for new year 2006 @ text @d3 1 a3 1 ** Copyright (c) 1999-2006 Ralf S. Engelschall @ 1.26 log @Adjusted all copyright messages for new year 2005. @ text @d3 1 a3 1 ** Copyright (c) 1999-2005 Ralf S. Engelschall @ 1.25 log @Adjusted all copyright messages for new year 2004. @ text @d3 1 a3 1 ** Copyright (c) 1999-2004 Ralf S. Engelschall @ 1.24 log @Adjusted all copyright messages for new year 2003. @ text @d3 1 a3 1 ** Copyright (c) 1999-2003 Ralf S. Engelschall @ 1.23 log @Internally switch from "errno_shield {...}" to "pth_shield {...}" and from "return_errno(..)" to "return pth_error(...)" in order to make the internal error handling a little bit more consistent. @ text @d3 1 a3 1 ** Copyright (c) 1999-2002 Ralf S. Engelschall @ 1.22 log @remove trailing whitespaces @ text @d231 1 a231 1 return_errno(FALSE, EINVAL); @ 1.21 log @bump copyright year @ text @d47 1 a47 1 if (r == NULL) @ 1.20 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2001 Ralf S. Engelschall @ 1.19 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2000 Ralf S. Engelschall @ 1.18 log @*** empty log message *** @ text @d29 13 d44 2 a45 1 intern void pth_ring_init(pth_ring_t *r, pth_ringnode_t *rn) d47 4 a50 6 if (r != NULL) r->rn_hook = NULL; if (rn != NULL) { rn->rn_next = rn; rn->rn_prev = rn; } d54 5 a58 6 intern int pth_ring_empty(pth_ring_t *r) { if (r == NULL) return FALSE; return (r->rn_hook == NULL ? TRUE : FALSE); } d60 5 a64 4 intern int pth_ring_elements(pth_ring_t *r) { int n; pth_ringnode_t *rn; d66 5 a70 12 if (r == NULL) return -1; n = 0; rn = r->rn_hook; if (rn != NULL) { do { n++; rn = rn->rn_next; } while (rn != r->rn_hook); } return n; } d72 1 d75 1 a75 1 (((r) == NULL || (rn) == NULL) ? NULL : (rn)->rn_next) d78 1 d81 1 a81 1 (((r) == NULL || (rn) == NULL) ? NULL : (rn)->rn_prev) d84 1 d86 2 a87 2 #define pth_ring_first(r) \ ((r) == NULL ? NULL : (r)->rn_hook) d90 1 a90 9 intern pth_ringnode_t *pth_ring_last(pth_ring_t *r) { if (r == NULL) return NULL; if (r->rn_hook == NULL) return NULL; return r->rn_hook->rn_prev; } d99 1 d103 1 d112 1 d116 2 a117 1 intern void pth_ring_remove(pth_ring_t *r, pth_ringnode_t *rn) d121 2 a122 2 if (r->rn_hook == rn && rn->rn_prev == rn && rn->rn_next == rn) r->rn_hook = NULL; d124 2 a125 2 if (r->rn_hook == rn) r->rn_hook = rn->rn_next; d129 1 a129 2 rn->rn_next = rn; rn->rn_prev = rn; d133 1 d138 2 a139 2 if (r->rn_hook == NULL) { r->rn_hook = rn; d144 2 a145 2 rn->rn_next = r->rn_hook; rn->rn_prev = r->rn_hook->rn_prev; d148 1 a148 1 r->rn_hook = rn; d150 1 d154 1 d159 2 a160 2 if (r->rn_hook == NULL) { r->rn_hook = rn; d165 2 a166 2 rn->rn_next = r->rn_hook; rn->rn_prev = r->rn_hook->rn_prev; d170 1 d174 1 d180 1 a180 5 #if cpp #define pth_ring_unshift(r, rn) \ pth_ring_append((r), (rn)) #endif d187 1 a187 1 pth_ring_remove(r, rn); d191 24 a214 1 intern pth_ringnode_t *pth_ring_shift(pth_ring_t *r) d220 1 a220 1 pth_ring_remove(r, rn); d222 22 @ 1.17 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999 Ralf S. Engelschall @ 1.16 log @*** empty log message *** @ text @d25 3 a27 3 /* ``Unix was not designed to stop people from doing stupid things, because that would also stop them from doing clever @ 1.15 log @*** empty log message *** @ text @d2 1 a2 2 ** pth_ring.c -- Pth ring data structure ** d22 2 @ 1.15.2.1 log @*** empty log message *** @ text @d2 2 a3 1 ** GNU Pth - The GNU Portable Threads a22 2 ** ** pth_ring.c: Pth ring data structure @ 1.14 log @*** empty log message *** @ text @d12 1 a12 1 ** version 2 of the License, or (at your option) any later version. @ 1.13 log @*** empty log message *** @ text @d10 1 a10 1 ** modify it under the terms of the GNU Library General Public d17 1 a17 1 ** Library General Public License for more details. d19 1 a19 1 ** You should have received a copy of the GNU Library General Public @ 1.12 log @*** empty log message *** @ text @d66 14 a79 20 intern pth_ringnode_t *pth_ring_next(pth_ring_t *r, pth_ringnode_t *rn) { if (r == NULL || rn == NULL) return NULL; return rn->rn_next; } intern pth_ringnode_t *pth_ring_prev(pth_ring_t *r, pth_ringnode_t *rn) { if (r == NULL || rn == NULL) return NULL; return rn->rn_prev; } intern pth_ringnode_t *pth_ring_first(pth_ring_t *r) { if (r == NULL) return NULL; return r->rn_hook; } d166 9 a174 11 intern void pth_ring_push(pth_ring_t *r, pth_ringnode_t *rn) { pth_ring_prepend(r, rn); return; } intern void pth_ring_unshift(pth_ring_t *r, pth_ringnode_t *rn) { pth_ring_append(r, rn); return; } @ 1.11 log @*** empty log message *** @ text @d24 4 a27 1 @ 1.10 log @*** empty log message *** @ text @d65 1 a65 1 if (rn == NULL) d72 1 a72 1 if (rn == NULL) d86 2 @ 1.10.2.1 log @*** empty log message *** @ text @d65 1 a65 1 if (r == NULL || rn == NULL) d72 1 a72 1 if (r == NULL || rn == NULL) a85 2 if (r == NULL) return NULL; @ 1.9 log @*** empty log message *** @ text @d2 1 a2 1 ** pth_ring.c -- PTH ring data structure @ 1.8 log @*** empty log message *** @ text @d6 2 a7 2 ** This file is part of PTH, a non-preemptive thread scheduling library ** which can be found at http://www.gnu.org/software/pth/. @ 1.7 log @*** empty log message *** @ text @d7 1 a7 1 ** which can be found at http://www.engelschall.com/sw/pth/. @ 1.6 log @*** empty log message *** @ text @d20 1 a20 1 ** License along with this library; if not, write to the Free @ 1.5 log @*** empty log message *** @ text @d32 2 a33 2 rn->rn_next = NULL; rn->rn_prev = NULL; a123 2 rn->rn_next = NULL; rn->rn_prev = NULL; d125 2 @ 1.4 log @*** empty log message *** @ text @d27 1 a27 1 void pth_ring_init(pth_ring_t *r, pth_ringnode_t *rn) d38 1 a38 1 int pth_ring_empty(pth_ring_t *r) d45 1 a45 1 int pth_ring_elements(pth_ring_t *r) d63 1 a63 1 pth_ringnode_t *pth_ring_next(pth_ring_t *r, pth_ringnode_t *rn) d70 1 a70 1 pth_ringnode_t *pth_ring_prev(pth_ring_t *r, pth_ringnode_t *rn) d77 1 a77 1 pth_ringnode_t *pth_ring_first(pth_ring_t *r) d84 1 a84 1 pth_ringnode_t *pth_ring_last(pth_ring_t *r) d91 1 a91 1 void pth_ring_insert_after(pth_ring_t *r, pth_ringnode_t *rn1, pth_ringnode_t *rn2) d102 1 a102 1 void pth_ring_insert_before(pth_ring_t *r, pth_ringnode_t *rn1, pth_ringnode_t *rn2) d113 1 a113 1 void pth_ring_remove(pth_ring_t *r, pth_ringnode_t *rn) d130 1 a130 1 void pth_ring_prepend(pth_ring_t *r, pth_ringnode_t *rn) d149 1 a149 1 void pth_ring_append(pth_ring_t *r, pth_ringnode_t *rn) d167 1 a167 1 void pth_ring_push(pth_ring_t *r, pth_ringnode_t *rn) d173 1 a173 1 void pth_ring_unshift(pth_ring_t *r, pth_ringnode_t *rn) d179 1 a179 1 pth_ringnode_t *pth_ring_pop(pth_ring_t *r) d189 1 a189 1 pth_ringnode_t *pth_ring_shift(pth_ring_t *r) @ 1.3 log @*** empty log message *** @ text @a62 7 int pth_ring_linked(pth_ring_t *r, pth_ringnode_t *rn) { if (rn == NULL) return FALSE; return ((rn->rn_next != NULL || rn->rn_prev != NULL) ? TRUE : FALSE); } @ 1.2 log @*** empty log message *** @ text @d6 1 a6 1 ** This file is part of PTH, a non-preemtive thread scheduling library @ 1.1 log @*** empty log message *** @ text @a0 40 /* ==================================================================== * Copyright (c) 1999 Ralf S. Engelschall. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall ." * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall ." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ d2 21 a22 2 ** Non-Preemtive Scheduler Library (PTH) ** pth_ring.c -- ring data structure implementation @