xref: /minix3/minix/lib/libddekit/src/lock.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
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)24 void 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)36 void 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)47 void 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)55 void 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)87 int 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)100 void 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)115 int ddekit_lock_owner(ddekit_lock_t *mtx) {
116 	return ddekit_thread_get_id((*mtx)->owner);
117 }
118 
119