1 /*-------------------------------------------------------------
3 semaphore.c -- Thread subsystem IV
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
29 -------------------------------------------------------------*/
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) \
44 if(((hndl)==LWP_SEM_NULL) || (LWP_OBJTYPE(hndl)!=LWP_OBJTYPE_SEM)) \
49 typedef struct _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
)
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()
78 __lwp_thread_dispatchdisable();
79 sema
= (sema_st
*)__lwp_objmgr_allocate(&_lwp_sema_objects
);
81 __lwp_objmgr_open(&_lwp_sema_objects
,&sema
->object
);
84 __lwp_thread_dispatchenable();
88 s32
LWP_SemInit(sem_t
*sem
,u32 start
,u32 max
)
95 ret
= __lwp_sema_allocate();
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();
107 s32
LWP_SemWait(sem_t 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
:
120 case LWP_SEMA_UNSATISFIED_NOWAIT
:
122 case LWP_SEMA_DELETED
:
124 case LWP_SEMA_TIMEOUT
:
131 s32
LWP_SemPost(sem_t 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();
144 s32
LWP_SemDestroy(sem_t 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
);