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