#include "common.h" #include #include #include #include #include #ifdef DDEBUG_LEVEL_SEMAPHORE #undef DDEBUG #define DDEBUG DDEBUG_LEVEL_SEMAPHORE #endif #include "debug.h" #include "thread.h" struct ddekit_sem { unsigned count; ddekit_thread_t *wait_queue; }; #define SEM_DEBUG(p) \ do { \ DDEBUG_MSG_VERBOSE("%s, %p, %d\n",__func__, sem, sem->count); \ } while(0) /***************************************************************************** * ddekit_sem_init * *************************+**************************************************/ PUBLIC ddekit_sem_t *ddekit_sem_init(int value) { ddekit_sem_t *sem; sem = (ddekit_sem_t *) ddekit_simple_malloc(sizeof(ddekit_sem_t)); sem->count = value; sem->wait_queue = NULL; SEM_DEBUG(p); return sem; } /***************************************************************************** * ddekit_sem_deinit * ****************************************************************************/ PUBLIC void ddekit_sem_deinit(ddekit_sem_t *sem) { SEM_DEBUG(p); ddekit_simple_free(sem); } /***************************************************************************** * ddekit_sem_down * ****************************************************************************/ PUBLIC void ddekit_sem_down(ddekit_sem_t *sem) { SEM_DEBUG(p); if(sem->count == 0) { if(sem->wait_queue == NULL) { sem->wait_queue = ddekit_thread_myself(); } else { ddekit_thread_t *pos = sem->wait_queue; while(pos->next != NULL) { pos = pos->next; } pos->next = ddekit_thread_myself(); } _ddekit_thread_schedule(); } else { sem->count--; } } /***************************************************************************** * ddekit_sem_down_try * ****************************************************************************/ PUBLIC int ddekit_sem_down_try(ddekit_sem_t *sem) { if(sem->count == 0) { return -1; } sem->count--; return 0; } /***************************************************************************** * ddekit_sem_up * ****************************************************************************/ PUBLIC void ddekit_sem_up(ddekit_sem_t *sem) { SEM_DEBUG(p); if (sem->wait_queue == NULL) { sem->count++; return; } else { ddekit_thread_t *waiter = sem->wait_queue; sem->wait_queue = waiter->next; waiter->next = NULL; _ddekit_thread_enqueue(waiter); ddekit_thread_schedule(); } } /**************************************************************************** * ddekit_sem_down_timed * ***************************************************************************/ PUBLIC int ddekit_sem_down_timed(ddekit_sem_t *sem, int timo ) { ddekit_panic("not implemented!"); return 0; }