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