xref: /minix/minix/lib/libddekit/src/semaphore.c (revision 83133719)
1 #include "common.h"
2 #include <ddekit/condvar.h>
3 #include <ddekit/lock.h>
4 #include <ddekit/memory.h>
5 #include <ddekit/panic.h>
6 #include <ddekit/semaphore.h>
7 
8 #ifdef DDEBUG_LEVEL_SEMAPHORE
9 #undef DDEBUG
10 #define DDEBUG DDEBUG_LEVEL_SEMAPHORE
11 #endif
12 
13 #include "debug.h"
14 #include "thread.h"
15 
16 struct ddekit_sem {
17 	unsigned count;
18 	ddekit_thread_t *wait_queue;
19 };
20 
21 #define SEM_DEBUG(p)                                                  \
22     do {                                                              \
23 		DDEBUG_MSG_VERBOSE("%s, %p, %d\n",__func__, sem, sem->count); \
24 	} while(0)
25 
26 /*****************************************************************************
27  *     ddekit_sem_init                                                       *
28  *************************+**************************************************/
29 ddekit_sem_t *ddekit_sem_init(int value)
30 {
31 	ddekit_sem_t *sem;
32 
33 	sem = (ddekit_sem_t *) ddekit_simple_malloc(sizeof(ddekit_sem_t));
34 
35 	sem->count = value;
36 	sem->wait_queue = NULL;
37 
38 	SEM_DEBUG(p);
39 	return sem;
40 }
41 
42 /*****************************************************************************
43  *     ddekit_sem_deinit                                                     *
44  ****************************************************************************/
45 void ddekit_sem_deinit(ddekit_sem_t *sem)
46 {
47 	SEM_DEBUG(p);
48 	ddekit_simple_free(sem);
49 }
50 
51 /*****************************************************************************
52  *     ddekit_sem_down                                                       *
53  ****************************************************************************/
54 void ddekit_sem_down(ddekit_sem_t *sem)
55 {
56 	SEM_DEBUG(p);
57 	if(sem->count == 0) {
58 		if(sem->wait_queue == NULL) {
59 			sem->wait_queue = ddekit_thread_myself();
60 		} else {
61 			ddekit_thread_t *pos = sem->wait_queue;
62 			while(pos->next != NULL) {
63 				pos = pos->next;
64 			}
65 			pos->next = ddekit_thread_myself();
66 		}
67 		_ddekit_thread_schedule();
68 	} else {
69 		sem->count--;
70 	}
71 }
72 
73 /*****************************************************************************
74  *     ddekit_sem_down_try                                                   *
75  ****************************************************************************/
76 int ddekit_sem_down_try(ddekit_sem_t *sem)
77 {
78 	if(sem->count == 0) {
79 		return -1;
80 	}
81 	sem->count--;
82 	return 0;
83 }
84 
85 /*****************************************************************************
86  *     ddekit_sem_up                                                         *
87  ****************************************************************************/
88 void ddekit_sem_up(ddekit_sem_t *sem)
89 {
90 	SEM_DEBUG(p);
91 	if (sem->wait_queue == NULL) {
92 		sem->count++;
93 		return;
94 	} else {
95 		ddekit_thread_t *waiter = sem->wait_queue;
96 		sem->wait_queue = waiter->next;
97 		waiter->next = NULL;
98 		_ddekit_thread_enqueue(waiter);
99 		ddekit_thread_schedule();
100 	}
101 }
102 
103 /****************************************************************************
104  *     ddekit_sem_down_timed                                                *
105  ***************************************************************************/
106 int ddekit_sem_down_timed(ddekit_sem_t *sem, int timo )
107 {
108 	ddekit_panic("not implemented!");
109 	return 0;
110 }
111 
112