18ccd4a63SDavid du Colombier #include <u.h> 28ccd4a63SDavid du Colombier #include <libc.h> 38ccd4a63SDavid du Colombier 4*96cbc34fSDavid du Colombier #ifdef PTHREAD 5*96cbc34fSDavid du Colombier 6*96cbc34fSDavid du Colombier static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER; 7*96cbc34fSDavid du Colombier 8*96cbc34fSDavid du Colombier static void lockinit(Lock * lk)9*96cbc34fSDavid du Colombierlockinit(Lock *lk) 10*96cbc34fSDavid du Colombier { 11*96cbc34fSDavid du Colombier pthread_mutexattr_t attr; 12*96cbc34fSDavid du Colombier 13*96cbc34fSDavid du Colombier pthread_mutex_lock(&initmutex); 14*96cbc34fSDavid du Colombier if(lk->init == 0){ 15*96cbc34fSDavid du Colombier pthread_mutexattr_init(&attr); 16*96cbc34fSDavid du Colombier pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); 17*96cbc34fSDavid du Colombier pthread_mutex_init(&lk->mutex, &attr); 18*96cbc34fSDavid du Colombier pthread_mutexattr_destroy(&attr); 19*96cbc34fSDavid du Colombier lk->init = 1; 20*96cbc34fSDavid du Colombier } 21*96cbc34fSDavid du Colombier pthread_mutex_unlock(&initmutex); 22*96cbc34fSDavid du Colombier } 23*96cbc34fSDavid du Colombier 24*96cbc34fSDavid du Colombier void lock(Lock * lk)25*96cbc34fSDavid du Colombierlock(Lock *lk) 26*96cbc34fSDavid du Colombier { 27*96cbc34fSDavid du Colombier if(!lk->init) 28*96cbc34fSDavid du Colombier lockinit(lk); 29*96cbc34fSDavid du Colombier if(pthread_mutex_lock(&lk->mutex) != 0) 30*96cbc34fSDavid du Colombier abort(); 31*96cbc34fSDavid du Colombier } 32*96cbc34fSDavid du Colombier 33*96cbc34fSDavid du Colombier int canlock(Lock * lk)34*96cbc34fSDavid du Colombiercanlock(Lock *lk) 35*96cbc34fSDavid du Colombier { 36*96cbc34fSDavid du Colombier int r; 37*96cbc34fSDavid du Colombier 38*96cbc34fSDavid du Colombier if(!lk->init) 39*96cbc34fSDavid du Colombier lockinit(lk); 40*96cbc34fSDavid du Colombier r = pthread_mutex_trylock(&lk->mutex); 41*96cbc34fSDavid du Colombier if(r == 0) 42*96cbc34fSDavid du Colombier return 1; 43*96cbc34fSDavid du Colombier if(r == EBUSY) 44*96cbc34fSDavid du Colombier return 0; 45*96cbc34fSDavid du Colombier abort(); 46*96cbc34fSDavid du Colombier } 47*96cbc34fSDavid du Colombier 48*96cbc34fSDavid du Colombier void unlock(Lock * lk)49*96cbc34fSDavid du Colombierunlock(Lock *lk) 50*96cbc34fSDavid du Colombier { 51*96cbc34fSDavid du Colombier if(pthread_mutex_unlock(&lk->mutex) != 0) 52*96cbc34fSDavid du Colombier abort(); 53*96cbc34fSDavid du Colombier } 54*96cbc34fSDavid du Colombier 55*96cbc34fSDavid du Colombier #else 56*96cbc34fSDavid du Colombier 57*96cbc34fSDavid du Colombier /* old, non-pthread systems */ 58*96cbc34fSDavid du Colombier 598ccd4a63SDavid du Colombier int canlock(Lock * lk)608ccd4a63SDavid du Colombiercanlock(Lock *lk) 618ccd4a63SDavid du Colombier { 628ccd4a63SDavid du Colombier return !tas(&lk->key); 638ccd4a63SDavid du Colombier } 648ccd4a63SDavid du Colombier 658ccd4a63SDavid du Colombier void lock(Lock * lk)668ccd4a63SDavid du Colombierlock(Lock *lk) 678ccd4a63SDavid du Colombier { 688ccd4a63SDavid du Colombier int i; 698ccd4a63SDavid du Colombier 708ccd4a63SDavid du Colombier /* easy case */ 718ccd4a63SDavid du Colombier if(canlock(lk)) 728ccd4a63SDavid du Colombier return; 738ccd4a63SDavid du Colombier 748ccd4a63SDavid du Colombier /* for multi processor machines */ 758ccd4a63SDavid du Colombier for(i=0; i<100; i++) 768ccd4a63SDavid du Colombier if(canlock(lk)) 778ccd4a63SDavid du Colombier return; 788ccd4a63SDavid du Colombier 798ccd4a63SDavid du Colombier for(i=0; i<100; i++) { 808ccd4a63SDavid du Colombier osyield(); 818ccd4a63SDavid du Colombier if(canlock(lk)) 828ccd4a63SDavid du Colombier return; 838ccd4a63SDavid du Colombier } 848ccd4a63SDavid du Colombier 858ccd4a63SDavid du Colombier /* looking bad - make sure it is not a priority problem */ 868ccd4a63SDavid du Colombier for(i=0; i<12; i++) { 878ccd4a63SDavid du Colombier osmsleep(1<<i); 888ccd4a63SDavid du Colombier if(canlock(lk)) 898ccd4a63SDavid du Colombier return; 908ccd4a63SDavid du Colombier } 918ccd4a63SDavid du Colombier 928ccd4a63SDavid du Colombier /* we are in trouble */ 938ccd4a63SDavid du Colombier for(;;) { 948ccd4a63SDavid du Colombier if(canlock(lk)) 958ccd4a63SDavid du Colombier return; 96ec59a3ddSDavid du Colombier iprint("lock loop %ld: val=%d &lock=%ux pc=%p\n", getpid(), lk->key, lk, getcallerpc(&lk)); 978ccd4a63SDavid du Colombier osmsleep(1000); 988ccd4a63SDavid du Colombier } 998ccd4a63SDavid du Colombier } 1008ccd4a63SDavid du Colombier 1018ccd4a63SDavid du Colombier void unlock(Lock * lk)1028ccd4a63SDavid du Colombierunlock(Lock *lk) 1038ccd4a63SDavid du Colombier { 1048ccd4a63SDavid du Colombier assert(lk->key); 1058ccd4a63SDavid du Colombier lk->key = 0; 1068ccd4a63SDavid du Colombier } 1078ccd4a63SDavid du Colombier 108*96cbc34fSDavid du Colombier #endif 109*96cbc34fSDavid du Colombier 1108ccd4a63SDavid du Colombier void ilock(Lock * lk)1118ccd4a63SDavid du Colombierilock(Lock *lk) 1128ccd4a63SDavid du Colombier { 1138ccd4a63SDavid du Colombier lock(lk); 1148ccd4a63SDavid du Colombier } 1158ccd4a63SDavid du Colombier 1168ccd4a63SDavid du Colombier void iunlock(Lock * lk)1178ccd4a63SDavid du Colombieriunlock(Lock *lk) 1188ccd4a63SDavid du Colombier { 1198ccd4a63SDavid du Colombier unlock(lk); 1208ccd4a63SDavid du Colombier } 121