smb improvements (rodries)
[libogc.git] / libogc / lwp_sema.c
blob49b1901da2f00de6639976fe7b8f49f2f1b69466
1 #include "asm.h"
2 #include "lwp_sema.h"
4 void __lwp_sema_initialize(lwp_sema *sema,lwp_semattr *attrs,u32 init_count)
6 sema->attrs = *attrs;
7 sema->count = init_count;
9 __lwp_threadqueue_init(&sema->wait_queue,__lwp_sema_ispriority(attrs)?LWP_THREADQ_MODEPRIORITY:LWP_THREADQ_MODEFIFO,LWP_STATES_WAITING_FOR_SEMAPHORE,LWP_SEMA_TIMEOUT);
12 u32 __lwp_sema_surrender(lwp_sema *sema,u32 id)
14 u32 level,ret;
15 lwp_cntrl *thethread;
17 ret = LWP_SEMA_SUCCESSFUL;
18 if((thethread=__lwp_threadqueue_dequeue(&sema->wait_queue))) return ret;
19 else {
20 _CPU_ISR_Disable(level);
21 if(sema->count<=sema->attrs.max_cnt)
22 ++sema->count;
23 else
24 ret = LWP_SEMA_MAXCNT_EXCEEDED;
25 _CPU_ISR_Restore(level);
27 return ret;
30 u32 __lwp_sema_seize(lwp_sema *sema,u32 id,u32 wait,u64 timeout)
32 u32 level;
33 lwp_cntrl *exec;
35 exec = _thr_executing;
36 exec->wait.ret_code = LWP_SEMA_SUCCESSFUL;
38 _CPU_ISR_Disable(level);
39 if(sema->count!=0) {
40 --sema->count;
41 _CPU_ISR_Restore(level);
42 return LWP_SEMA_SUCCESSFUL;
45 if(!wait) {
46 _CPU_ISR_Restore(level);
47 exec->wait.ret_code = LWP_SEMA_UNSATISFIED_NOWAIT;
48 return LWP_SEMA_UNSATISFIED_NOWAIT;
51 __lwp_threadqueue_csenter(&sema->wait_queue);
52 exec->wait.queue = &sema->wait_queue;
53 exec->wait.id = id;
54 _CPU_ISR_Restore(level);
56 __lwp_threadqueue_enqueue(&sema->wait_queue,timeout);
57 return LWP_SEMA_SUCCESSFUL;
60 void __lwp_sema_flush(lwp_sema *sema,u32 status)
62 __lwp_threadqueue_flush(&sema->wait_queue,status);