1 #include "asm.h"
2 #include "lwp_mutex.h"
3
__lwp_mutex_initialize(lwp_mutex * mutex,lwp_mutex_attr * attrs,u32 init_lock)4 void __lwp_mutex_initialize(lwp_mutex *mutex,lwp_mutex_attr *attrs,u32 init_lock)
5 {
6 mutex->atrrs = *attrs;
7 mutex->lock = init_lock;
8 mutex->blocked_cnt = 0;
9
10 if(init_lock==LWP_MUTEX_LOCKED) {
11 mutex->nest_cnt = 1;
12 mutex->holder = _thr_executing;
13 if(__lwp_mutex_isinheritprio(attrs) || __lwp_mutex_isprioceiling(attrs))
14 _thr_executing->res_cnt++;
15 } else {
16 mutex->nest_cnt = 0;
17 mutex->holder = NULL;
18 }
19
20 __lwp_threadqueue_init(&mutex->wait_queue,__lwp_mutex_isfifo(attrs)?LWP_THREADQ_MODEFIFO:LWP_THREADQ_MODEPRIORITY,LWP_STATES_WAITING_FOR_MUTEX,LWP_MUTEX_TIMEOUT);
21 }
22
__lwp_mutex_surrender(lwp_mutex * mutex)23 u32 __lwp_mutex_surrender(lwp_mutex *mutex)
24 {
25 lwp_cntrl *thethread;
26 lwp_cntrl *holder;
27
28 holder = mutex->holder;
29
30 if(mutex->atrrs.onlyownerrelease) {
31 if(!__lwp_thread_isexec(holder))
32 return LWP_MUTEX_NOTOWNER;
33 }
34
35 if(!mutex->nest_cnt)
36 return LWP_MUTEX_SUCCESSFUL;
37
38 mutex->nest_cnt--;
39 if(mutex->nest_cnt!=0) {
40 switch(mutex->atrrs.nest_behavior) {
41 case LWP_MUTEX_NEST_ACQUIRE:
42 return LWP_MUTEX_SUCCESSFUL;
43 case LWP_MUTEX_NEST_ERROR:
44 return LWP_MUTEX_NEST_NOTALLOWED;
45 case LWP_MUTEX_NEST_BLOCK:
46 break;
47 }
48 }
49
50 if(__lwp_mutex_isinheritprio(&mutex->atrrs) || __lwp_mutex_isprioceiling(&mutex->atrrs))
51 holder->res_cnt--;
52
53 mutex->holder = NULL;
54 if(__lwp_mutex_isinheritprio(&mutex->atrrs) || __lwp_mutex_isprioceiling(&mutex->atrrs)) {
55 if(holder->res_cnt==0 && holder->real_prio!=holder->cur_prio)
56 __lwp_thread_changepriority(holder,holder->real_prio,TRUE);
57 }
58
59 if((thethread=__lwp_threadqueue_dequeue(&mutex->wait_queue))) {
60 mutex->nest_cnt = 1;
61 mutex->holder = thethread;
62 if(__lwp_mutex_isinheritprio(&mutex->atrrs) || __lwp_mutex_isprioceiling(&mutex->atrrs))
63 thethread->res_cnt++;
64 } else
65 mutex->lock = LWP_MUTEX_UNLOCKED;
66
67 return LWP_MUTEX_SUCCESSFUL;
68 }
69
__lwp_mutex_seize_irq_blocking(lwp_mutex * mutex,u64 timeout)70 void __lwp_mutex_seize_irq_blocking(lwp_mutex *mutex,u64 timeout)
71 {
72 lwp_cntrl *exec;
73
74 exec = _thr_executing;
75 if(__lwp_mutex_isinheritprio(&mutex->atrrs)){
76 if(mutex->holder->cur_prio>exec->cur_prio)
77 __lwp_thread_changepriority(mutex->holder,exec->cur_prio,FALSE);
78 }
79
80 mutex->blocked_cnt++;
81 __lwp_threadqueue_enqueue(&mutex->wait_queue,timeout);
82
83 if(_thr_executing->wait.ret_code==LWP_MUTEX_SUCCESSFUL) {
84 if(__lwp_mutex_isprioceiling(&mutex->atrrs)) {
85 if(mutex->atrrs.prioceil<exec->cur_prio)
86 __lwp_thread_changepriority(exec,mutex->atrrs.prioceil,FALSE);
87 }
88 }
89 __lwp_thread_dispatchenable();
90 }
91
__lwp_mutex_flush(lwp_mutex * mutex,u32 status)92 void __lwp_mutex_flush(lwp_mutex *mutex,u32 status)
93 {
94 __lwp_threadqueue_flush(&mutex->wait_queue,status);
95 }
96