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