clear SBSS section
[libogc.git] / libogc / semaphore.c
blob8b45111e921b31bf984f7b5d649fc61457256699
1 /*-------------------------------------------------------------
3 semaphore.c -- Thread subsystem IV
5 Copyright (C) 2004
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
9 This software is provided 'as-is', without any express or implied
10 warranty. In no event will the authors be held liable for any
11 damages arising from the use of this software.
13 Permission is granted to anyone to use this software for any
14 purpose, including commercial applications, and to alter it and
15 redistribute it freely, subject to the following restrictions:
17 1. The origin of this software must not be misrepresented; you
18 must not claim that you wrote the original software. If you use
19 this software in a product, an acknowledgment in the product
20 documentation would be appreciated but is not required.
22 2. Altered source versions must be plainly marked as such, and
23 must not be misrepresented as being the original software.
25 3. This notice may not be removed or altered from any source
26 distribution.
29 -------------------------------------------------------------*/
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <asm.h>
35 #include "lwp_sema.h"
36 #include "lwp_objmgr.h"
37 #include "lwp_config.h"
38 #include "semaphore.h"
40 #define LWP_OBJTYPE_SEM 4
42 #define LWP_CHECK_SEM(hndl) \
43 { \
44 if(((hndl)==LWP_SEM_NULL) || (LWP_OBJTYPE(hndl)!=LWP_OBJTYPE_SEM)) \
45 return NULL; \
49 typedef struct _sema_st
51 lwp_obj object;
52 lwp_sema sema;
53 } sema_st;
55 lwp_objinfo _lwp_sema_objects;
57 void __lwp_sema_init()
59 __lwp_objmgr_initinfo(&_lwp_sema_objects,LWP_MAX_SEMAS,sizeof(sema_st));
62 static __inline__ sema_st* __lwp_sema_open(sem_t sem)
64 LWP_CHECK_SEM(sem);
65 return (sema_st*)__lwp_objmgr_get(&_lwp_sema_objects,LWP_OBJMASKID(sem));
68 static __inline__ void __lwp_sema_free(sema_st *sema)
70 __lwp_objmgr_close(&_lwp_sema_objects,&sema->object);
71 __lwp_objmgr_free(&_lwp_sema_objects,&sema->object);
74 static sema_st* __lwp_sema_allocate()
76 sema_st *sema;
78 __lwp_thread_dispatchdisable();
79 sema = (sema_st*)__lwp_objmgr_allocate(&_lwp_sema_objects);
80 if(sema) {
81 __lwp_objmgr_open(&_lwp_sema_objects,&sema->object);
82 return sema;
84 __lwp_thread_dispatchenable();
85 return NULL;
88 s32 LWP_SemInit(sem_t *sem,u32 start,u32 max)
90 lwp_semattr attr;
91 sema_st *ret;
93 if(!sem) return -1;
95 ret = __lwp_sema_allocate();
96 if(!ret) return -1;
98 attr.max_cnt = max;
99 attr.mode = LWP_SEMA_MODEFIFO;
100 __lwp_sema_initialize(&ret->sema,&attr,start);
102 *sem = (sem_t)(LWP_OBJMASKTYPE(LWP_OBJTYPE_SEM)|LWP_OBJMASKID(ret->object.id));
103 __lwp_thread_dispatchenable();
104 return 0;
107 s32 LWP_SemWait(sem_t sem)
109 sema_st *lwp_sem;
111 lwp_sem = __lwp_sema_open(sem);
112 if(!lwp_sem) return -1;
114 __lwp_sema_seize(&lwp_sem->sema,lwp_sem->object.id,TRUE,LWP_THREADQ_NOTIMEOUT);
115 __lwp_thread_dispatchenable();
117 switch(_thr_executing->wait.ret_code) {
118 case LWP_SEMA_SUCCESSFUL:
119 break;
120 case LWP_SEMA_UNSATISFIED_NOWAIT:
121 return EAGAIN;
122 case LWP_SEMA_DELETED:
123 return EAGAIN;
124 case LWP_SEMA_TIMEOUT:
125 return ETIMEDOUT;
128 return 0;
131 s32 LWP_SemPost(sem_t sem)
133 sema_st *lwp_sem;
135 lwp_sem = __lwp_sema_open(sem);
136 if(!lwp_sem) return -1;
138 __lwp_sema_surrender(&lwp_sem->sema,lwp_sem->object.id);
139 __lwp_thread_dispatchenable();
141 return 0;
144 s32 LWP_SemDestroy(sem_t sem)
146 sema_st *lwp_sem;
148 lwp_sem = __lwp_sema_open(sem);
149 if(!lwp_sem) return -1;
151 __lwp_sema_flush(&lwp_sem->sema,-1);
152 __lwp_thread_dispatchenable();
154 __lwp_sema_free(lwp_sem);
155 return 0;