Skip to content

Commit 81cbeee

Browse files
committed
Add LWP_DetachThread
1 parent d796fc7 commit 81cbeee

4 files changed

Lines changed: 56 additions & 11 deletions

File tree

gc/ogc/lwp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,15 @@ void LWP_ExitThread(void *value_ptr) __attribute__((noreturn));
196196
s32 LWP_JoinThread(lwp_t thethread,void **value_ptr);
197197

198198

199+
/*! \fn s32 LWP_DetachThread(lwp_t thethread)
200+
\brief Detach the given thread.
201+
\param[in] thethread handle to the thread's context which should be detached. If NULL, the current thread will be taken.
202+
203+
\return 0 on success, non-zero on error
204+
*/
205+
s32 LWP_DetachThread(lwp_t thethread);
206+
207+
199208
/*! \fn s32 LWP_InitQueue(lwpq_t *thequeue)
200209
\brief Initialize the thread synchronization queue
201210
\param[in] thequeue pointer to a lwpq_t handle.

gc/ogc/lwp_threads.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,15 @@ extern "C" {
7272
typedef enum
7373
{
7474
LWP_CPU_BUDGET_ALGO_NONE = 0,
75-
LWP_CPU_BUDGET_ALGO_TIMESLICE
75+
LWP_CPU_BUDGET_ALGO_TIMESLICE
7676
} lwp_cpu_budget_algorithms;
7777

78+
typedef enum
79+
{
80+
LWP_DETACH_STATE_DETACHED = 0,
81+
LWP_DETACH_STATE_JOINABLE
82+
} lwp_detach_state;
83+
7884
typedef struct _lwpwaitinfo {
7985
u32 id;
8086
u32 cnt;
@@ -105,6 +111,7 @@ typedef struct _lwpcntrl {
105111
u32 stack_size;
106112
u8 stack_allocated;
107113
lwp_queue *ready;
114+
lwp_detach_state detach_state;
108115
lwp_thrqueue join_list;
109116
frame_context context; //16
110117
void *libc_reent;

libogc/lwp.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,16 @@ s32 LWP_JoinThread(lwp_t thethread,void **value_ptr)
364364
lwp_cntrl *exec,*lwp_thread;
365365

366366
lwp_thread = __lwp_cntrl_open(thethread);
367-
if(!lwp_thread) return EINVAL;
367+
if(!lwp_thread) return ESRCH;
368+
369+
if(lwp_thread->detach_state==LWP_DETACH_STATE_DETACHED) {
370+
__lwp_thread_dispatchenable();
371+
return EINVAL;
372+
}
368373

369374
if(__lwp_thread_isexec(lwp_thread)) {
370375
__lwp_thread_dispatchenable();
371-
return EDEADLK; //EDEADLK
376+
return EDEADLK;
372377
}
373378

374379
if(__lwp_statewaitjoinatexit(lwp_thread->cur_state)) {
@@ -392,6 +397,27 @@ s32 LWP_JoinThread(lwp_t thethread,void **value_ptr)
392397
return 0;
393398
}
394399

400+
s32 LWP_DetachThread(lwp_t thethread)
401+
{
402+
lwp_cntrl *lwp_thread;
403+
404+
if(thethread==LWP_THREAD_NULL) thethread = LWP_GetSelf();
405+
406+
lwp_thread = __lwp_cntrl_open(thethread);
407+
if(!lwp_thread) return ESRCH;
408+
409+
if(lwp_thread->detach_state==LWP_DETACH_STATE_DETACHED) {
410+
__lwp_thread_dispatchenable();
411+
return EINVAL;
412+
}
413+
414+
lwp_thread->detach_state = LWP_DETACH_STATE_DETACHED;
415+
__lwp_thread_clearstate(lwp_thread,LWP_STATES_WAITING_FOR_JOINATEXIT);
416+
__lwp_thread_dispatchenable();
417+
418+
return 0;
419+
}
420+
395421
s32 LWP_InitQueue(lwpq_t *thequeue)
396422
{
397423
tqueue_st *tq;

libogc/lwp_threads.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ u32 __lwp_thread_init(lwp_cntrl *thethread,void *stack_area,u32 stack_size,u32 p
646646
}
647647
thethread->stack_size = act_stack_size;
648648

649+
thethread->detach_state = LWP_DETACH_STATE_JOINABLE;
649650
__lwp_threadqueue_init(&thethread->join_list,LWP_THREADQ_MODEFIFO,LWP_STATES_WAITING_FOR_JOIN,0);
650651

651652
memset(&thethread->context,0,sizeof(thethread->context));
@@ -720,14 +721,16 @@ void __lwp_thread_exit(lwp_cntrl *thethread,void *value_ptr)
720721

721722
__lwp_thread_dispatchdisable();
722723
thethread->wait.ret_arg = value_ptr;
723-
if((p=__lwp_threadqueue_dequeue(&thethread->join_list))) {
724-
do {
725-
*(void**)p->wait.ret_arg = value_ptr;
726-
} while((p=__lwp_threadqueue_dequeue(&thethread->join_list)));
727-
} else {
728-
__lwp_thread_setstate(thethread,LWP_STATES_WAITING_FOR_JOINATEXIT);
729-
__lwp_thread_dispatchenable();
730-
__lwp_thread_dispatchdisable();
724+
if(thethread->detach_state==LWP_DETACH_STATE_JOINABLE) {
725+
if((p=__lwp_threadqueue_dequeue(&thethread->join_list))) {
726+
do {
727+
*(void**)p->wait.ret_arg = value_ptr;
728+
} while((p=__lwp_threadqueue_dequeue(&thethread->join_list)));
729+
} else {
730+
__lwp_thread_setstate(thethread,LWP_STATES_WAITING_FOR_JOINATEXIT);
731+
__lwp_thread_dispatchenable();
732+
__lwp_thread_dispatchdisable();
733+
}
731734
}
732735
__lwp_thread_close(thethread);
733736
__lwp_thread_dispatchenable();

0 commit comments

Comments
 (0)