diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/libc/lock.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/libc/lock.c')
-rwxr-xr-x | sys/src/cmd/unix/drawterm/libc/lock.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/libc/lock.c b/sys/src/cmd/unix/drawterm/libc/lock.c new file mode 100755 index 000000000..07d435256 --- /dev/null +++ b/sys/src/cmd/unix/drawterm/libc/lock.c @@ -0,0 +1,120 @@ +#include <u.h> +#include <libc.h> + +#ifdef PTHREAD + +static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER; + +static void +lockinit(Lock *lk) +{ + pthread_mutexattr_t attr; + + pthread_mutex_lock(&initmutex); + if(lk->init == 0){ + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&lk->mutex, &attr); + pthread_mutexattr_destroy(&attr); + lk->init = 1; + } + pthread_mutex_unlock(&initmutex); +} + +void +lock(Lock *lk) +{ + if(!lk->init) + lockinit(lk); + if(pthread_mutex_lock(&lk->mutex) != 0) + abort(); +} + +int +canlock(Lock *lk) +{ + int r; + + if(!lk->init) + lockinit(lk); + r = pthread_mutex_trylock(&lk->mutex); + if(r == 0) + return 1; + if(r == EBUSY) + return 0; + abort(); +} + +void +unlock(Lock *lk) +{ + if(pthread_mutex_unlock(&lk->mutex) != 0) + abort(); +} + +#else + +/* old, non-pthread systems */ + +int +canlock(Lock *lk) +{ + return !tas(&lk->key); +} + +void +lock(Lock *lk) +{ + int i; + + /* easy case */ + if(canlock(lk)) + return; + + /* for multi processor machines */ + for(i=0; i<100; i++) + if(canlock(lk)) + return; + + for(i=0; i<100; i++) { + osyield(); + if(canlock(lk)) + return; + } + + /* looking bad - make sure it is not a priority problem */ + for(i=0; i<12; i++) { + osmsleep(1<<i); + if(canlock(lk)) + return; + } + + /* we are in trouble */ + for(;;) { + if(canlock(lk)) + return; + iprint("lock loop %ld: val=%d &lock=%ux pc=%p\n", getpid(), lk->key, lk, getcallerpc(&lk)); + osmsleep(1000); + } +} + +void +unlock(Lock *lk) +{ + assert(lk->key); + lk->key = 0; +} + +#endif + +void +ilock(Lock *lk) +{ + lock(lk); +} + +void +iunlock(Lock *lk) +{ + unlock(lk); +} |