optimize the menuconfig redrawing
[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 static inline bool must_inline
6 __mutex_check_owner(mutex_t* mutex)
7 {
8     return mutex->owner == __current->pid;
9 }
10
11 static inline void must_inline
12 __mutext_lock(mutex_t* mutex)
13 {
14     while (atomic_load(&mutex->lk)) {
15         preempt_current();
16     }
17
18     atomic_fetch_add(&mutex->lk, 1);
19     mutex->owner = __current->pid;
20 }
21
22 static inline void must_inline
23 __mutext_unlock(mutex_t* mutex)
24 {
25     if (__mutex_check_owner(mutex))
26         atomic_fetch_sub(&mutex->lk, 1);
27 }
28
29 void
30 mutex_lock(mutex_t* mutex)
31 {
32     __mutext_lock(mutex);
33 }
34
35 void
36 mutex_unlock(mutex_t* mutex)
37 {
38     __mutext_unlock(mutex);
39 }
40
41 void
42 mutex_unlock_for(mutex_t* mutex, pid_t pid)
43 {
44     if (mutex->owner != pid || !atomic_load(&mutex->lk)) {
45         return;
46     }
47     __mutext_unlock(mutex);
48 }
49
50 void
51 mutex_lock_nested(mutex_t* mutex)
52 {
53     if (atomic_load(&mutex->lk) && __mutex_check_owner(mutex)) {
54         atomic_fetch_add(&mutex->lk, 1);
55         return;
56     }
57
58     __mutext_lock(mutex);
59 }
60
61 void
62 mutex_unlock_nested(mutex_t* mutex)
63 {
64     mutex_unlock_for(mutex, __current->pid);
65 }