head 1.43; access; symbols PTH_2_0_7:1.42 PTH_2_0_6:1.41 PTH_2_0_5:1.41 PTH_2_0_4:1.41 PTH_2_0_3:1.40 PTH_2_0_2:1.40 PTH_2_0_1:1.40 PTH_2_0_0:1.39 PTH_2_0b2:1.38 PTH_2_0b1:1.38 PTH_2_0b0:1.38 PTH_1_4:1.36.0.2 PTH_1_4_1:1.36 PTH_1_4_0:1.35 PTH_1_3_7:1.33 PTH_1_4a3:1.34 PTH_1_3_6:1.33 PTH_1_4a2:1.34 PTH_1_3_5:1.33 PTH_1_4a1:1.34 PTH_1_3_4:1.33 PTH_1_3:1.33.0.2 PTH_1_3_3:1.33 PTH_1_3_2:1.32 PTH_1_3_1:1.31 PTH_1_3_0:1.31 PTH_1_3b3:1.31 PTH_1_2_3:1.28.2.1 PTH_1_3b2:1.31 PTH_1_3b1:1.31 PTH_1_3a5:1.31 PTH_1_3a4:1.31 PTH_1_3a3:1.31 PTH_1_2_2:1.28.2.1 PTH_1_3a2:1.31 PTH_1_2_1:1.28.2.1 PTH_1_3a1:1.29 PTH_1_2:1.28.0.2 PTH_1_2_0:1.28 PTH_1_2b8:1.27 PTH_1_2b7:1.27 PTH_1_1_6:1.24 PTH_1_2b6:1.26 PTH_1_2b5:1.26 PTH_1_2b4:1.26 PTH_1_2b3:1.26 PTH_1_2b2:1.24 PTH_1_2b1:1.24 PTH_1_1_5:1.24 PTH_1_0_6:1.17.2.2 PTH_1_0_5:1.17.2.1 PTH_1_0:1.17.0.2 PTH_1_1:1.24.0.2 PTH_1_1_4:1.24 PTH_1_1_3:1.24 PTH_1_1_2:1.24 PTH_1_1_1:1.24 PTH_1_1_0:1.24 PTH_1_1b7:1.23 PTH_1_1b6:1.23 PTH_1_1b5:1.23 PTH_1_1b4:1.21 PTH_1_1b3:1.20 PTH_1_1b2:1.20 PTH_1_1b1:1.19 PTH_1_0_4:1.17 PTH_1_0_3:1.17 PTH_1_0_2:1.17 PTH_1_0_1:1.17 PTH_1_0_0:1.16 PTH_1_0b8:1.16 PTH_1_0b7:1.15 PTH_1_0b6:1.15 PTH_1_0b5:1.15 PTH_1_0b4:1.15 PTH_1_0b3:1.13 PTH_1_0b2:1.13 PTH_1_0b1:1.12 PTH_0_9_21:1.12 PTH_0_9_20:1.12 PTH_0_9_19:1.8; locks; strict; comment @ * @; 1.43 date 2007.01.01.18.23.53; author rse; state Exp; branches; next 1.42; commitid 9DhdiirNzQPBIP0s; 1.42 date 2006.06.08.17.54.53; author rse; state Exp; branches; next 1.41; commitid x8N3mLVdQgkbdeAr; 1.41 date 2004.12.31.19.34.45; author rse; state Exp; branches; next 1.40; 1.40 date 2004.07.13.10.50.49; author rse; state Exp; branches; next 1.39; 1.39 date 2003.01.01.15.49.12; author rse; state Exp; branches; next 1.38; 1.38 date 2002.11.05.19.39.09; author rse; state Exp; branches; next 1.37; 1.37 date 2002.10.24.15.21.14; author rse; state Exp; branches; next 1.36; 1.36 date 2002.01.27.11.03.41; author rse; state Exp; branches; next 1.35; 1.35 date 2001.03.24.14.51.05; author rse; state Exp; branches; next 1.34; 1.34 date 2000.03.12.16.43.17; author rse; state Exp; branches; next 1.33; 1.33 date 2000.03.10.09.43.08; author rse; state Exp; branches; next 1.32; 1.32 date 2000.02.24.12.35.01; author rse; state Exp; branches; next 1.31; 1.31 date 99.12.30.21.59.01; author rse; state Exp; branches; next 1.30; 1.30 date 99.11.09.08.11.32; author rse; state Exp; branches; next 1.29; 1.29 date 99.11.01.10.27.20; author rse; state Exp; branches; next 1.28; 1.28 date 99.10.31.11.46.13; author rse; state Exp; branches 1.28.2.1; next 1.27; 1.27 date 99.10.22.10.48.21; author rse; state Exp; branches; next 1.26; 1.26 date 99.09.17.08.01.55; author rse; state Exp; branches; next 1.25; 1.25 date 99.09.09.17.36.26; author rse; state Exp; branches; next 1.24; 1.24 date 99.08.19.15.08.53; author rse; state Exp; branches; next 1.23; 1.23 date 99.08.17.08.08.36; author rse; state Exp; branches; next 1.22; 1.22 date 99.08.16.10.39.06; author rse; state Exp; branches; next 1.21; 1.21 date 99.08.13.13.19.49; author rse; state Exp; branches; next 1.20; 1.20 date 99.08.10.07.48.42; author rse; state Exp; branches; next 1.19; 1.19 date 99.08.03.12.29.46; author rse; state Exp; branches; next 1.18; 1.18 date 99.08.03.12.28.42; author rse; state Exp; branches; next 1.17; 1.17 date 99.07.22.11.14.05; author rse; state Exp; branches 1.17.2.1; next 1.16; 1.16 date 99.07.16.07.59.27; author rse; state Exp; branches; next 1.15; 1.15 date 99.07.08.10.34.01; author rse; state Exp; branches; next 1.14; 1.14 date 99.07.08.10.19.11; author rse; state Exp; branches; next 1.13; 1.13 date 99.07.04.12.05.35; author rse; state Exp; branches; next 1.12; 1.12 date 99.06.25.15.28.13; author rse; state Exp; branches; next 1.11; 1.11 date 99.06.24.11.50.04; author rse; state Exp; branches; next 1.10; 1.10 date 99.06.24.11.25.07; author rse; state Exp; branches; next 1.9; 1.9 date 99.06.24.10.54.29; author rse; state Exp; branches; next 1.8; 1.8 date 99.06.21.15.41.33; author rse; state Exp; branches; next 1.7; 1.7 date 99.06.21.15.36.42; author rse; state Exp; branches; next 1.6; 1.6 date 99.06.21.15.24.04; author rse; state Exp; branches; next 1.5; 1.5 date 99.06.21.14.26.50; author rse; state Exp; branches; next 1.4; 1.4 date 99.06.21.14.24.47; author rse; state Exp; branches; next 1.3; 1.3 date 99.06.21.10.31.29; author rse; state Exp; branches; next 1.2; 1.2 date 99.06.21.10.07.29; author rse; state Exp; branches; next 1.1; 1.1 date 99.06.21.09.52.44; author rse; state Exp; branches; next ; 1.28.2.1 date 99.11.01.10.25.01; author rse; state Exp; branches; next ; 1.17.2.1 date 99.08.31.08.30.29; author rse; state Exp; branches; next 1.17.2.2; 1.17.2.2 date 99.08.31.08.32.18; author rse; state Exp; branches; next ; desc @@ 1.43 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_sync.c: Pth synchronization facilities */ /* ``It is hard to fly with the eagles when you work with the turkeys.'' -- Unknown */ #include "pth_p.h" /* ** Mutual Exclusion Locks */ int pth_mutex_init(pth_mutex_t *mutex) { if (mutex == NULL) return pth_error(FALSE, EINVAL); mutex->mx_state = PTH_MUTEX_INITIALIZED; mutex->mx_owner = NULL; mutex->mx_count = 0; return TRUE; } int pth_mutex_acquire(pth_mutex_t *mutex, int tryonly, pth_event_t ev_extra) { static pth_key_t ev_key = PTH_KEY_INIT; pth_event_t ev; pth_debug2("pth_mutex_acquire: called from thread \"%s\"", pth_current->name); /* consistency checks */ if (mutex == NULL) return pth_error(FALSE, EINVAL); if (!(mutex->mx_state & PTH_MUTEX_INITIALIZED)) return pth_error(FALSE, EDEADLK); /* still not locked, so simply acquire mutex? */ if (!(mutex->mx_state & PTH_MUTEX_LOCKED)) { mutex->mx_state |= PTH_MUTEX_LOCKED; mutex->mx_owner = pth_current; mutex->mx_count = 1; pth_ring_append(&(pth_current->mutexring), &(mutex->mx_node)); pth_debug1("pth_mutex_acquire: immediately locking mutex"); return TRUE; } /* already locked by caller? */ if (mutex->mx_count >= 1 && mutex->mx_owner == pth_current) { /* recursive lock */ mutex->mx_count++; pth_debug1("pth_mutex_acquire: recursive locking"); return TRUE; } /* should we just tryonly? */ if (tryonly) return pth_error(FALSE, EBUSY); /* else wait for mutex to become unlocked.. */ pth_debug1("pth_mutex_acquire: wait until mutex is unlocked"); for (;;) { ev = pth_event(PTH_EVENT_MUTEX|PTH_MODE_STATIC, &ev_key, mutex); if (ev_extra != NULL) pth_event_concat(ev, ev_extra, NULL); pth_wait(ev); if (ev_extra != NULL) { pth_event_isolate(ev); if (pth_event_status(ev) == PTH_STATUS_PENDING) return pth_error(FALSE, EINTR); } if (!(mutex->mx_state & PTH_MUTEX_LOCKED)) break; } /* now it's again unlocked, so acquire mutex */ pth_debug1("pth_mutex_acquire: locking mutex"); mutex->mx_state |= PTH_MUTEX_LOCKED; mutex->mx_owner = pth_current; mutex->mx_count = 1; pth_ring_append(&(pth_current->mutexring), &(mutex->mx_node)); return TRUE; } int pth_mutex_release(pth_mutex_t *mutex) { /* consistency checks */ if (mutex == NULL) return pth_error(FALSE, EINVAL); if (!(mutex->mx_state & PTH_MUTEX_INITIALIZED)) return pth_error(FALSE, EDEADLK); if (!(mutex->mx_state & PTH_MUTEX_LOCKED)) return pth_error(FALSE, EDEADLK); if (mutex->mx_owner != pth_current) return pth_error(FALSE, EACCES); /* decrement recursion counter and release mutex */ mutex->mx_count--; if (mutex->mx_count <= 0) { mutex->mx_state &= ~(PTH_MUTEX_LOCKED); mutex->mx_owner = NULL; mutex->mx_count = 0; pth_ring_delete(&(pth_current->mutexring), &(mutex->mx_node)); } return TRUE; } intern void pth_mutex_releaseall(pth_t thread) { pth_ringnode_t *rn, *rnf; if (thread == NULL) return; /* iterate over all mutexes of thread */ rn = rnf = pth_ring_first(&(thread->mutexring)); while (rn != NULL) { pth_mutex_release((pth_mutex_t *)rn); rn = pth_ring_next(&(thread->mutexring), rn); if (rn == rnf) break; } return; } /* ** Read-Write Locks */ int pth_rwlock_init(pth_rwlock_t *rwlock) { if (rwlock == NULL) return pth_error(FALSE, EINVAL); rwlock->rw_state = PTH_RWLOCK_INITIALIZED; rwlock->rw_readers = 0; pth_mutex_init(&(rwlock->rw_mutex_rd)); pth_mutex_init(&(rwlock->rw_mutex_rw)); return TRUE; } int pth_rwlock_acquire(pth_rwlock_t *rwlock, int op, int tryonly, pth_event_t ev_extra) { /* consistency checks */ if (rwlock == NULL) return pth_error(FALSE, EINVAL); if (!(rwlock->rw_state & PTH_RWLOCK_INITIALIZED)) return pth_error(FALSE, EDEADLK); /* acquire lock */ if (op == PTH_RWLOCK_RW) { /* read-write lock is simple */ if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), tryonly, ev_extra)) return FALSE; rwlock->rw_mode = PTH_RWLOCK_RW; } else { /* read-only lock is more complicated to get right */ if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), tryonly, ev_extra)) return FALSE; rwlock->rw_readers++; if (rwlock->rw_readers == 1) { if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), tryonly, ev_extra)) { rwlock->rw_readers--; pth_shield { pth_mutex_release(&(rwlock->rw_mutex_rd)); } return FALSE; } } rwlock->rw_mode = PTH_RWLOCK_RD; pth_mutex_release(&(rwlock->rw_mutex_rd)); } return TRUE; } int pth_rwlock_release(pth_rwlock_t *rwlock) { /* consistency checks */ if (rwlock == NULL) return pth_error(FALSE, EINVAL); if (!(rwlock->rw_state & PTH_RWLOCK_INITIALIZED)) return pth_error(FALSE, EDEADLK); /* release lock */ if (rwlock->rw_mode == PTH_RWLOCK_RW) { /* read-write unlock is simple */ if (!pth_mutex_release(&(rwlock->rw_mutex_rw))) return FALSE; } else { /* read-only unlock is more complicated to get right */ if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), FALSE, NULL)) return FALSE; rwlock->rw_readers--; if (rwlock->rw_readers == 0) { if (!pth_mutex_release(&(rwlock->rw_mutex_rw))) { rwlock->rw_readers++; pth_shield { pth_mutex_release(&(rwlock->rw_mutex_rd)); } return FALSE; } } rwlock->rw_mode = PTH_RWLOCK_RD; pth_mutex_release(&(rwlock->rw_mutex_rd)); } return TRUE; } /* ** Condition Variables */ int pth_cond_init(pth_cond_t *cond) { if (cond == NULL) return pth_error(FALSE, EINVAL); cond->cn_state = PTH_COND_INITIALIZED; cond->cn_waiters = 0; return TRUE; } static void pth_cond_cleanup_handler(void *_cleanvec) { pth_mutex_t *mutex = (pth_mutex_t *)(((void **)_cleanvec)[0]); pth_cond_t *cond = (pth_cond_t *)(((void **)_cleanvec)[1]); /* re-acquire mutex when pth_cond_await() is cancelled in order to restore the condition variable semantics */ pth_mutex_acquire(mutex, FALSE, NULL); /* fix number of waiters */ cond->cn_waiters--; return; } int pth_cond_await(pth_cond_t *cond, pth_mutex_t *mutex, pth_event_t ev_extra) { static pth_key_t ev_key = PTH_KEY_INIT; void *cleanvec[2]; pth_event_t ev; /* consistency checks */ if (cond == NULL || mutex == NULL) return pth_error(FALSE, EINVAL); if (!(cond->cn_state & PTH_COND_INITIALIZED)) return pth_error(FALSE, EDEADLK); /* check whether we can do a short-circuit wait */ if ( (cond->cn_state & PTH_COND_SIGNALED) && !(cond->cn_state & PTH_COND_BROADCAST)) { cond->cn_state &= ~(PTH_COND_SIGNALED); cond->cn_state &= ~(PTH_COND_BROADCAST); cond->cn_state &= ~(PTH_COND_HANDLED); return TRUE; } /* add us to the number of waiters */ cond->cn_waiters++; /* release mutex (caller had to acquire it first) */ pth_mutex_release(mutex); /* wait until the condition is signaled */ ev = pth_event(PTH_EVENT_COND|PTH_MODE_STATIC, &ev_key, cond); if (ev_extra != NULL) pth_event_concat(ev, ev_extra, NULL); cleanvec[0] = mutex; cleanvec[1] = cond; pth_cleanup_push(pth_cond_cleanup_handler, cleanvec); pth_wait(ev); pth_cleanup_pop(FALSE); if (ev_extra != NULL) pth_event_isolate(ev); /* reacquire mutex */ pth_mutex_acquire(mutex, FALSE, NULL); /* remove us from the number of waiters */ cond->cn_waiters--; /* release mutex (caller had to acquire it first) */ return TRUE; } int pth_cond_notify(pth_cond_t *cond, int broadcast) { /* consistency checks */ if (cond == NULL) return pth_error(FALSE, EINVAL); if (!(cond->cn_state & PTH_COND_INITIALIZED)) return pth_error(FALSE, EDEADLK); /* do something only if there is at least one waiters (POSIX semantics) */ if (cond->cn_waiters > 0) { /* signal the condition */ cond->cn_state |= PTH_COND_SIGNALED; if (broadcast) cond->cn_state |= PTH_COND_BROADCAST; else cond->cn_state &= ~(PTH_COND_BROADCAST); cond->cn_state &= ~(PTH_COND_HANDLED); /* and give other threads a chance to awake */ pth_yield(NULL); } /* return to caller */ return TRUE; } /* ** Barriers */ int pth_barrier_init(pth_barrier_t *barrier, int threshold) { if (barrier == NULL || threshold <= 0) return pth_error(FALSE, EINVAL); if (!pth_mutex_init(&(barrier->br_mutex))) return FALSE; if (!pth_cond_init(&(barrier->br_cond))) return FALSE; barrier->br_state = PTH_BARRIER_INITIALIZED; barrier->br_threshold = threshold; barrier->br_count = threshold; barrier->br_cycle = FALSE; return TRUE; } int pth_barrier_reach(pth_barrier_t *barrier) { int cancel, cycle; int rv; if (barrier == NULL) return pth_error(FALSE, EINVAL); if (!(barrier->br_state & PTH_BARRIER_INITIALIZED)) return pth_error(FALSE, EINVAL); if (!pth_mutex_acquire(&(barrier->br_mutex), FALSE, NULL)) return FALSE; cycle = barrier->br_cycle; if (--(barrier->br_count) == 0) { /* last thread reached the barrier */ barrier->br_cycle = !(barrier->br_cycle); barrier->br_count = barrier->br_threshold; if ((rv = pth_cond_notify(&(barrier->br_cond), TRUE))) rv = PTH_BARRIER_TAILLIGHT; } else { /* wait until remaining threads have reached the barrier, too */ pth_cancel_state(PTH_CANCEL_DISABLE, &cancel); if (barrier->br_threshold == barrier->br_count) rv = PTH_BARRIER_HEADLIGHT; else rv = TRUE; while (cycle == barrier->br_cycle) { if (!(rv = pth_cond_await(&(barrier->br_cond), &(barrier->br_mutex), NULL))) break; } pth_cancel_state(cancel, NULL); } pth_mutex_release(&(barrier->br_mutex)); return rv; } @ 1.42 log @Adjusted all copyright messages for new year 2006 @ text @d3 1 a3 1 ** Copyright (c) 1999-2006 Ralf S. Engelschall @ 1.41 log @Adjusted all copyright messages for new year 2005. @ text @d3 1 a3 1 ** Copyright (c) 1999-2005 Ralf S. Engelschall @ 1.40 log @Adjusted all copyright messages for new year 2004. @ text @d3 1 a3 1 ** Copyright (c) 1999-2004 Ralf S. Engelschall @ 1.39 log @Adjusted all copyright messages for new year 2003. @ text @d3 1 a3 1 ** Copyright (c) 1999-2003 Ralf S. Engelschall @ 1.38 log @1. The function "int pth_event_occurred(pth_event_t)" was replaced with "pth_status_t pth_event_status(pth_event_t)" where pth_status_t can have values of PTH_STATUS_PENDING (replacing the old FALSE return value of pth_event_occurred), PTH_STATUS_OCCURRED (replacing the old TRUE return value of pth_event_occurred), and PTH_STATUS_FAILED (a new return value indicating an error in processing the event). This was scheduler/event-manager errors can be indicated which happended while processing the event. For backward compatibility reasons, a macro pth_event_occurred() was added. This will be removed soon. 2. Use the new PTH_STATUS_FAILED event status in the scheduler's event-manager for filedescriptor events if the internal select(2) call returned with an error. Additionally this PTH_STATUS_FAILED is recognized by the high-level API functions (pth_select, etc) and produce the necessary POSIX conforming return codes (usually -1 and errno == EBADF). Parts submitted by: Thanh Luu @ text @d3 1 a3 1 ** Copyright (c) 1999-2002 Ralf S. Engelschall @ 1.37 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 @d89 1 a89 1 if (!pth_event_occurred(ev)) @ 1.36 log @bump copyright year @ text @d38 1 a38 1 return_errno(FALSE, EINVAL); d54 1 a54 1 return_errno(FALSE, EINVAL); d56 1 a56 1 return_errno(FALSE, EDEADLK); d78 1 a78 1 return_errno(FALSE, EBUSY); d90 1 a90 1 return_errno(FALSE, EINTR); d109 1 a109 1 return_errno(FALSE, EINVAL); d111 1 a111 1 return_errno(FALSE, EDEADLK); d113 1 a113 1 return_errno(FALSE, EDEADLK); d115 1 a115 1 return_errno(FALSE, EACCES); d152 1 a152 1 return_errno(FALSE, EINVAL); d164 1 a164 1 return_errno(FALSE, EINVAL); d166 1 a166 1 return_errno(FALSE, EDEADLK); d183 1 a183 1 errno_shield { pth_mutex_release(&(rwlock->rw_mutex_rd)); } d197 1 a197 1 return_errno(FALSE, EINVAL); d199 1 a199 1 return_errno(FALSE, EDEADLK); d215 1 a215 1 errno_shield { pth_mutex_release(&(rwlock->rw_mutex_rd)); } d232 1 a232 1 return_errno(FALSE, EINVAL); d260 1 a260 1 return_errno(FALSE, EINVAL); d262 1 a262 1 return_errno(FALSE, EDEADLK); d305 1 a305 1 return_errno(FALSE, EINVAL); d307 1 a307 1 return_errno(FALSE, EDEADLK); d334 1 a334 1 return_errno(FALSE, EINVAL); d352 1 a352 1 return_errno(FALSE, EINVAL); d354 1 a354 1 return_errno(FALSE, EINVAL); @ 1.35 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2001 Ralf S. Engelschall @ 1.34 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2000 Ralf S. Engelschall @ 1.33 log @*** empty log message *** @ text @a38 1 pth_ring_init(NULL, &mutex->mx_node); d123 1 a123 1 pth_ring_remove(&(pth_current->mutexring), &(mutex->mx_node)); @ 1.32 log @*** empty log message *** @ text @d234 2 a235 1 cond->cn_state = PTH_COND_INITIALIZED; d239 1 a239 1 static void pth_cond_cleanup_handler(void *_mutex) d241 2 a242 1 pth_mutex_t *mutex = (pth_mutex_t *)_mutex; d247 3 d256 1 d274 3 d284 3 a286 1 pth_cleanup_push(pth_cond_cleanup_handler, mutex); d294 5 d310 9 a318 7 /* signal the condition */ cond->cn_state |= PTH_COND_SIGNALED; if (broadcast) cond->cn_state |= PTH_COND_BROADCAST; else cond->cn_state &= ~(PTH_COND_BROADCAST); cond->cn_state &= ~(PTH_COND_HANDLED); d320 3 a322 2 /* and give other threads a chance to awake */ pth_yield(NULL); @ 1.31 log @*** empty log message *** @ text @d83 1 a83 1 while (1) { @ 1.30 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999 Ralf S. Engelschall @ 1.29 log @*** empty log message *** @ text @d65 1 a65 1 pth_debug1("pth_mutex_acquire: immediately locking mutex"); d68 1 a68 1 d73 1 a73 1 pth_debug1("pth_mutex_acquire: recursive locking"); d79 1 a79 1 return_errno(FALSE, EBUSY); d82 1 a82 1 pth_debug1("pth_mutex_acquire: wait until mutex is unlocked"); d98 1 a98 1 pth_debug1("pth_mutex_acquire: locking mutex"); d136 1 a136 1 rn = rnf = pth_ring_first(&(thread->mutexring)); d242 1 a242 1 /* re-acquire mutex when pth_cond_await() is cancelled @ 1.28 log @*** empty log message *** @ text @d2 1 a2 2 ** pth_sync.c -- Pth synchronization facilities ** d22 2 @ 1.28.2.1 log @*** empty log message *** @ text @d2 2 a3 1 ** GNU Pth - The GNU Portable Threads a22 2 ** ** pth_sync.c: Pth synchronization facilities @ 1.27 log @*** empty log message *** @ text @d12 1 a12 1 ** version 2 of the License, or (at your option) any later version. @ 1.26 log @*** empty log message *** @ text @d237 10 d274 1 d276 1 @ 1.25 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.24 log @*** empty log message *** @ text @d183 1 a183 3 errno_preserve; pth_mutex_release(&(rwlock->rw_mutex_rd)); errno_restore; d215 1 a215 3 errno_preserve; pth_mutex_release(&(rwlock->rw_mutex_rd)); errno_restore; @ 1.23 log @*** empty log message *** @ text @d24 4 a27 1 @ 1.22 log @*** empty log message *** @ text @d42 1 a42 1 int pth_mutex_acquire(pth_mutex_t *mutex, int try, pth_event_t ev_extra) d73 2 a74 2 /* should we just try? */ if (try) d157 1 a157 1 int pth_rwlock_acquire(pth_rwlock_t *rwlock, int op, int try, pth_event_t ev_extra) d168 1 a168 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), try, ev_extra)) d174 1 a174 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), try, ev_extra)) d178 1 a178 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), try, ev_extra)) { @ 1.21 log @*** empty log message *** @ text @d75 1 a75 1 return_errno(FALSE, EAGAIN); @ 1.20 log @*** empty log message *** @ text @a34 2 if (mutex->mx_state & PTH_MUTEX_LOCKED) return_errno(FALSE, EBUSY); @ 1.19 log @*** empty log message *** @ text @d127 1 a127 1 intern int pth_mutex_releaseall(pth_t thread) d129 1 a129 1 pth_ringnode_t *rn; d132 1 a132 1 return_errno(FALSE, EINVAL); d134 8 a141 5 for (rn = pth_ring_first(&(thread->mutexring)); rn != NULL; rn = pth_ring_next(&(thread->mutexring), rn) ) if (!pth_mutex_release((pth_mutex_t *)rn)) return FALSE; return TRUE; @ 1.18 log @*** empty log message *** @ text @d317 1 a317 1 int cancel, tmp, cycle; @ 1.17 log @*** empty log message *** @ text @d296 56 @ 1.17.2.1 log @*** empty log message *** @ text @d127 1 a127 1 intern void pth_mutex_releaseall(pth_t thread) d129 1 a129 1 pth_ringnode_t *rn, *rnf; d132 1 a132 1 return; d134 5 a138 8 rn = rnf = pth_ring_first(&(thread->mutexring)); while (rn != NULL) { pth_mutex_release((pth_mutex_t *)rn); rn = pth_ring_next(&(thread->mutexring), rn); if (rn == rnf) break; } return; @ 1.17.2.2 log @*** empty log message *** @ text @d35 2 d77 1 a77 1 return_errno(FALSE, EBUSY); @ 1.16 log @*** empty log message *** @ text @d75 1 a75 1 /* should we should try? */ @ 1.15 log @*** empty log message *** @ text @d49 2 d63 1 d71 1 d80 1 d96 1 d248 6 a253 2 /* check whether already signaled */ if (cond->cn_state & PTH_COND_SIGNALED) d255 1 a282 1 cond->cn_state &= ~(PTH_COND_HANDLED); d287 1 @ 1.14 log @*** empty log message *** @ text @d2 1 a2 1 ** pth_sync.c -- PTH synchronization facilities @ 1.13 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.12 log @*** empty log message *** @ text @d7 1 a7 1 ** which can be found at http://www.engelschall.com/sw/pth/. @ 1.11 log @*** empty log message *** @ text @d150 1 a150 1 int pth_rwlock_acquire(pth_rwlock_t *rwlock, int op, pth_event_t ev_extra) d161 1 a161 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), FALSE, ev_extra)) d167 1 a167 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), FALSE, ev_extra)) d171 1 a171 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), FALSE, ev_extra)) { @ 1.10 log @*** empty log message *** @ text @d53 1 a53 1 return_errno(FALSE, EINVAL); d102 1 a102 1 return FALSE; d104 1 a104 1 return FALSE; d106 1 a106 1 return FALSE; d108 1 a108 1 return FALSE; d121 1 a121 1 intern void pth_mutex_releaseall(pth_t thread) d126 1 a126 1 return; d130 3 a132 2 pth_mutex_release((pth_mutex_t *)rn); return; d142 1 a142 1 return FALSE; d154 1 a154 1 return FALSE; d156 1 a156 1 return FALSE; d173 1 d175 1 d189 1 a189 1 return FALSE; d191 1 a191 1 return FALSE; d207 1 d209 1 d226 1 a226 1 return FALSE; d238 1 a238 1 return FALSE; d240 1 a240 1 return FALSE; d266 1 a266 1 return FALSE; d268 1 a268 1 return FALSE; @ 1.9 log @*** empty log message *** @ text @d34 1 a34 1 return FALSE; d36 1 a36 1 return FALSE; d44 1 a44 1 int pth_mutex_acquire(pth_mutex_t *mutex, pth_event_t ev_extra) d51 1 a51 1 return FALSE; d53 1 a53 1 return FALSE; d71 4 d160 1 a160 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), ev_extra)) d166 1 a166 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), ev_extra)) d170 1 a170 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), ev_extra)) { d198 1 a198 1 if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), NULL)) d253 1 a253 1 pth_mutex_acquire(mutex, NULL); @ 1.8 log @*** empty log message *** @ text @d270 1 a270 1 pth_yield(); @ 1.7 log @*** empty log message *** @ text @d49 1 d54 2 a56 1 /* still not locked, so acquire mutex */ d63 18 a80 20 else { /* already locked */ if (mutex->mx_count >= 1 && mutex->mx_owner == pth_current) { /* recursive lock */ mutex->mx_count++; return TRUE; } /* wait for mutex to become unlocked */ while (1) { ev = pth_event(PTH_EVENT_MUTEX|PTH_MODE_STATIC, &ev_key, mutex); if (ev_extra != NULL) pth_event_concat(ev, ev_extra, NULL); pth_wait(ev); if (ev_extra != NULL) { pth_event_isolate(ev); if (!pth_event_occurred(ev)) return_errno(FALSE, EINTR); } if (!(mutex->mx_state & PTH_MUTEX_LOCKED)) break; d82 2 a83 6 /* now again unlocked, so acquire mutex */ mutex->mx_state |= PTH_MUTEX_LOCKED; mutex->mx_owner = pth_current; mutex->mx_count = 1; pth_ring_append(&(pth_current->mutexring), &(mutex->mx_node)); return TRUE; d85 7 a91 1 return FALSE; d96 1 d105 2 a108 1 /* release the mutex */ d123 1 d147 1 d152 2 d155 1 d161 1 d180 1 d185 2 d188 1 d193 1 d227 1 a229 1 /* consistency checks */ d232 1 d236 1 d239 1 d247 1 d255 1 a257 1 /* consistency checks */ d260 1 d268 1 d271 2 @ 1.6 log @*** empty log message *** @ text @a43 7 pth_t pth_mutex_holder(pth_mutex_t *mutex) { if (mutex == NULL) return NULL; return mutex->mx_owner; } a141 2 int rc; @ 1.5 log @*** empty log message *** @ text @d51 1 a51 1 int pth_mutex_acquire(pth_mutex_t *mutex, int poll, pth_event_t ev_extra) d75 10 a84 18 else if (poll) { /* lock polling */ return FALSE; } else { /* wait for mutex to become unlocked */ while (1) { ev = pth_event(PTH_EVENT_MUTEX|PTH_MODE_STATIC, &ev_key, mutex); if (ev_extra != NULL) pth_event_concat(ev, ev_extra, NULL); pth_wait(ev); if (ev_extra != NULL) { pth_event_isolate(ev); if (!pth_event_occurred(ev)) return_errno(FALSE, EINTR); } if (!(mutex->mx_state & PTH_MUTEX_LOCKED)) break; d86 2 a87 6 /* now again unlocked, so acquire mutex */ mutex->mx_state |= PTH_MUTEX_LOCKED; mutex->mx_owner = pth_current; mutex->mx_count = 1; pth_ring_append(&(pth_current->mutexring), &(mutex->mx_node)); return TRUE; d89 6 d133 72 d216 1 a216 1 int pth_cond_wait(pth_cond_t *cond, pth_mutex_t *mutex, pth_event_t ev_extra) d239 1 a239 1 pth_mutex_acquire(mutex, FALSE, NULL); @ 1.4 log @*** empty log message *** @ text @a162 2 /* mark condition as still not handled */ cond->cn_state &= ~(PTH_COND_HANDLED); d186 1 @ 1.3 log @*** empty log message *** @ text @d35 1 a35 1 if (mutex->state & PTH_MUTEX_LOCKED) d37 4 a40 3 mutex->state = PTH_MUTEX_INITIALIZED; mutex->owner = NULL; mutex->count = 0; d44 7 d58 1 a58 1 if (!(mutex->state & PTH_MUTEX_INITIALIZED)) d60 1 a60 1 if (!(mutex->state & PTH_MUTEX_LOCKED)) { d62 4 a65 3 mutex->state |= PTH_MUTEX_LOCKED; mutex->owner = pth_current; mutex->count = 1; d70 1 a70 1 if (mutex->count >= 1 && mutex->owner == pth_current) { d72 1 a72 1 mutex->count++; d91 1 a91 1 if (!(mutex->state & PTH_MUTEX_LOCKED)) d95 4 a98 3 mutex->state |= PTH_MUTEX_LOCKED; mutex->owner = pth_current; mutex->count = 1; d109 1 a109 1 if (!(mutex->state & PTH_MUTEX_INITIALIZED)) d111 1 a111 1 if (!(mutex->state & PTH_MUTEX_LOCKED)) d113 1 a113 1 if (mutex->owner != pth_current) d115 2 a116 2 mutex->count--; if (mutex->count <= 0) { d118 4 a121 3 mutex->state &= ~(PTH_MUTEX_LOCKED); mutex->owner = NULL; mutex->count = 0; d126 54 a179 1 pth_t pth_mutex_holder(pth_mutex_t *mutex) d181 14 a194 3 if (mutex == NULL) return NULL; return mutex->owner; @ 1.2 log @*** empty log message *** @ text @d115 7 @ 1.1 log @*** empty log message *** @ text @d43 1 a43 1 int pth_mutex_lock(pth_mutex_t *mutex, int poll, pth_event_t ev_extra) d95 1 a95 1 int pth_mutex_unlock(pth_mutex_t *mutex) @