fix dependency check logic cause config always disabled
[lunaix-os.git] / lunaix-os / kernel / ds / mutex.c
1 #include <lunaix/ds/mutex.h>
2 #include <lunaix/process.h>
3 #include <lunaix/kpreempt.h>
4
5 #define __do_lock(mutext)               \
6     ({                                  \
7         atomic_fetch_add(&mutex->lk, 1);\
8         mutex->owner = __current->pid;  \
9     })
10
11 static inline bool must_inline
12 __mutex_check_owner(mutex_t* mutex)
13 {
14     return mutex->owner == __current->pid;
15 }
16
17 static inline void must_inline
18 __mutext_lock(mutex_t* mutex)
19 {
20     while (atomic_load(&mutex->lk)) {
21         preempt_current();
22     }
23
24     __do_lock(mutex);
25 }
26
27 static inline void must_inline
28 __mutext_unlock(mutex_t* mutex)
29 {
30     if (__mutex_check_owner(mutex))
31         atomic_fetch_sub(&mutex->lk, 1);
32 }
33
34 void
35 mutex_lock(mutex_t* mutex)
36 {
37     __mutext_lock(mutex);
38 }
39
40 bool
41 mutex_trylock(mutex_t* mutex)
42 {
43     if (atomic_load(&mutex->lk))
44         return false;
45
46     __do_lock(mutex);
47     return true;
48 }
49
50 void
51 mutex_unlock(mutex_t* mutex)
52 {
53     __mutext_unlock(mutex);
54 }
55
56 void
57 mutex_unlock_for(mutex_t* mutex, pid_t pid)
58 {
59     if (mutex->owner != pid || !atomic_load(&mutex->lk)) {
60         return;
61     }
62     atomic_fetch_sub(&mutex->lk, 1);
63 }
64
65 void
66 mutex_lock_nested(mutex_t* mutex)
67 {
68     if (atomic_load(&mutex->lk) && __mutex_check_owner(mutex)) {
69         atomic_fetch_add(&mutex->lk, 1);
70         return;
71     }
72
73     __mutext_lock(mutex);
74 }
75
76 void
77 mutex_unlock_nested(mutex_t* mutex)
78 {
79     mutex_unlock_for(mutex, __current->pid);
80 }