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