clear SBSS section
[libogc.git] / libogc / lwp_mutex.inl
blobafa9c823963552a175ea1d965f71ea976b875898
1 #ifndef __LWP_MUTEX_INL__
2 #define __LWP_MUTEX_INL__
4 static __inline__ u32 __lwp_mutex_locked(lwp_mutex *mutex)
6         return (mutex->lock==LWP_MUTEX_LOCKED);
9 static __inline__ u32 __lwp_mutex_ispriority(lwp_mutex_attr *attrs)
11         return (attrs->mode==LWP_MUTEX_PRIORITY);
14 static __inline__ u32 __lwp_mutex_isfifo(lwp_mutex_attr *attrs)
16         return (attrs->mode==LWP_MUTEX_FIFO);
19 static __inline__ u32 __lwp_mutex_isinheritprio(lwp_mutex_attr *attrs)
21         return (attrs->mode==LWP_MUTEX_INHERITPRIO);
24 static __inline__ u32 __lwp_mutex_isprioceiling(lwp_mutex_attr *attrs)
26         return (attrs->mode==LWP_MUTEX_PRIORITYCEIL);
29 static __inline__ u32 __lwp_mutex_seize_irq_trylock(lwp_mutex *mutex,u32 *isr_level)
31         lwp_cntrl *exec;
32         u32 level = *isr_level;
34         exec = _thr_executing;
35         exec->wait.ret_code = LWP_MUTEX_SUCCESSFUL;
36         if(!__lwp_mutex_locked(mutex)) {
37                 mutex->lock = LWP_MUTEX_LOCKED;
38                 mutex->holder = exec;
39                 mutex->nest_cnt = 1;
40                 if(__lwp_mutex_isinheritprio(&mutex->atrrs) || __lwp_mutex_isprioceiling(&mutex->atrrs))
41                         exec->res_cnt++;
42                 if(!__lwp_mutex_isprioceiling(&mutex->atrrs)) {
43                         _CPU_ISR_Restore(level);
44                         return 0;
45                 }
46                 {
47                         u32 prioceiling,priocurr;
48                         
49                         prioceiling = mutex->atrrs.prioceil;
50                         priocurr = exec->cur_prio;
51                         if(priocurr==prioceiling) {
52                                 _CPU_ISR_Restore(level);
53                                 return 0;
54                         }
55                         if(priocurr>prioceiling) {
56                                 __lwp_thread_dispatchdisable();
57                                 _CPU_ISR_Restore(level);
58                                 __lwp_thread_changepriority(mutex->holder,mutex->atrrs.prioceil,FALSE);
59                                 __lwp_thread_dispatchenable();
60                                 return 0;
61                         }
62                         exec->wait.ret_code = LWP_MUTEX_CEILINGVIOL;
63                         mutex->nest_cnt = 0;
64                         exec->res_cnt--;
65                         _CPU_ISR_Restore(level);
66                         return 0;
67                 }
68                 return 0;
69         }
71         if(__lwp_thread_isexec(mutex->holder)) {
72                 switch(mutex->atrrs.nest_behavior) {
73                         case LWP_MUTEX_NEST_ACQUIRE:
74                                 mutex->nest_cnt++;
75                                 _CPU_ISR_Restore(level);
76                                 return 0;
77                         case LWP_MUTEX_NEST_ERROR:
78                                 exec->wait.ret_code = LWP_MUTEX_NEST_NOTALLOWED;
79                                 _CPU_ISR_Restore(level);
80                                 return 0;
81                         case LWP_MUTEX_NEST_BLOCK:
82                                 break;
83                 }
84         }
85         return 1;
88 #endif