1 #include "common.h" 2 3 #include <ddekit/assert.h> 4 #include <ddekit/memory.h> 5 #include <ddekit/semaphore.h> 6 7 #ifdef DDEBUG_LEVEL_LOCK 8 #undef DDEBUG 9 #define DDEBUG DDEBUG_LEVEL_LOCK 10 #endif 11 12 #include "debug.h" 13 #include "thread.h" 14 15 struct ddekit_lock { 16 ddekit_thread_t *owner; 17 ddekit_thread_t *wait_queue; 18 }; 19 20 21 /****************************************************************************** 22 * ddekit_lock_init_locked * 23 *****************************************************************************/ ddekit_lock_init_locked(ddekit_lock_t * mtx)24void ddekit_lock_init_locked(ddekit_lock_t *mtx) 25 { 26 (*mtx) = (struct ddekit_lock *) 27 ddekit_simple_malloc(sizeof(struct ddekit_lock)); 28 29 (*mtx)->wait_queue = NULL; 30 (*mtx)->owner = ddekit_thread_myself(); 31 } 32 33 /****************************************************************************** 34 * ddekit_lock_init_unlocked * 35 *****************************************************************************/ ddekit_lock_init_unlocked(ddekit_lock_t * mtx)36void ddekit_lock_init_unlocked(ddekit_lock_t *mtx) 37 { 38 (*mtx) = (struct ddekit_lock *) 39 ddekit_simple_malloc(sizeof(struct ddekit_lock)); 40 (*mtx)->owner = NULL; 41 (*mtx)->wait_queue = NULL; 42 } 43 44 /****************************************************************************** 45 * ddekit_lock_deinit * 46 *****************************************************************************/ ddekit_lock_deinit(ddekit_lock_t * mtx)47void ddekit_lock_deinit (ddekit_lock_t *mtx) 48 { 49 ddekit_simple_free(*mtx); 50 } 51 52 /****************************************************************************** 53 * ddekit_lock_lock * 54 *****************************************************************************/ ddekit_lock_lock(ddekit_lock_t * mtx)55void ddekit_lock_lock (ddekit_lock_t *mtx) 56 { 57 if ((*mtx)->owner == NULL) { 58 (*mtx)->owner = ddekit_thread_myself(); 59 } else { 60 61 if ((*mtx)->wait_queue == NULL) { 62 (*mtx)->wait_queue = ddekit_thread_myself(); 63 } else { 64 ddekit_thread_t *pos = (*mtx)->wait_queue; 65 while(pos->next != NULL) { 66 pos = pos->next; 67 } 68 pos->next = ddekit_thread_myself(); 69 } 70 71 _ddekit_thread_schedule(); 72 73 if ((*mtx)->owner != NULL) { 74 _ddekit_print_backtrace((*mtx)->owner); 75 _ddekit_print_backtrace(ddekit_thread_myself()); 76 ddekit_panic("owner!=NULL: %s (I am %s)\n", 77 (*mtx)->owner->name, ddekit_thread_myself()->name); 78 } 79 80 (*mtx)->owner = ddekit_thread_myself(); 81 } 82 } 83 84 /****************************************************************************** 85 * ddekit_lock_try_lock * 86 *****************************************************************************/ ddekit_lock_try_lock(ddekit_lock_t * mtx)87int ddekit_lock_try_lock(ddekit_lock_t *mtx) 88 { 89 if ((*mtx)->owner == NULL) { 90 (*mtx)->owner = ddekit_thread_myself(); 91 return 0; 92 } else { 93 return -1; 94 } 95 } 96 97 /****************************************************************************** 98 * ddekit_lock_unlock * 99 *****************************************************************************/ ddekit_lock_unlock(ddekit_lock_t * mtx)100void ddekit_lock_unlock (ddekit_lock_t *mtx) { 101 ddekit_assert((*mtx)->owner != NULL); 102 (*mtx)->owner = NULL; 103 if((*mtx)->wait_queue) { 104 ddekit_thread_t *waiter = (*mtx)->wait_queue; 105 (*mtx)->wait_queue = waiter->next; 106 waiter->next= NULL; 107 _ddekit_thread_enqueue(waiter); 108 ddekit_yield(); 109 } 110 } 111 112 /****************************************************************************** 113 * ddekit_lock_owner * 114 *****************************************************************************/ ddekit_lock_owner(ddekit_lock_t * mtx)115int ddekit_lock_owner(ddekit_lock_t *mtx) { 116 return ddekit_thread_get_id((*mtx)->owner); 117 } 118 119