Fix libogc hardware lighting (GX_SetChanCtrl) - patch from https://sourceforge.net...
[libogc.git] / libogc / lwp_mutex.c
blob205074a952cf5e7324fe91e9a22ab9e9d1d8fecb
1 #include "asm.h"
2 #include "lwp_mutex.h"
4 void __lwp_mutex_initialize(lwp_mutex *mutex,lwp_mutex_attr *attrs,u32 init_lock)
6 mutex->atrrs = *attrs;
7 mutex->lock = init_lock;
8 mutex->blocked_cnt = 0;
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;
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);
23 u32 __lwp_mutex_surrender(lwp_mutex *mutex)
25 lwp_cntrl *thethread;
26 lwp_cntrl *holder;
28 holder = mutex->holder;
30 if(mutex->atrrs.onlyownerrelease) {
31 if(!__lwp_thread_isexec(holder))
32 return LWP_MUTEX_NOTOWNER;
35 if(!mutex->nest_cnt)
36 return LWP_MUTEX_SUCCESSFUL;
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;
50 if(__lwp_mutex_isinheritprio(&mutex->atrrs) || __lwp_mutex_isprioceiling(&mutex->atrrs))
51 holder->res_cnt--;
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);
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;
67 return LWP_MUTEX_SUCCESSFUL;
70 void __lwp_mutex_seize_irq_blocking(lwp_mutex *mutex,u64 timeout)
72 lwp_cntrl *exec;
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);
80 mutex->blocked_cnt++;
81 __lwp_threadqueue_enqueue(&mutex->wait_queue,timeout);
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);
89 __lwp_thread_dispatchenable();
92 void __lwp_mutex_flush(lwp_mutex *mutex,u32 status)
94 __lwp_threadqueue_flush(&mutex->wait_queue,status);