ctr_firmware/trunk/bootrom/include/brom/os/common/thread.h
nakasima e781b2f723 glに合わせてOSi_→i_os変更。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@99 b871894f-2f95-9b40-918c-086798483c85
2008-12-10 10:33:22 +00:00

927 lines
29 KiB
C

/*---------------------------------------------------------------------------*
Project: CtrBrom - OS - include
File: thread.h
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef BROM_OS_THREAD_H_
#define BROM_OS_THREAD_H_
#include <brom/misc.h>
#include <brom/os/common/context.h>
//#include <brom/os/common/callTrace.h>
//#include <ctr/version.h>
#ifdef __cplusplus
extern "C" {
#endif
//---- build switch to let number of thread infinity, for version 3.0 or later
//#if SDK_VERSION_MAJOR >= 3
#define SDK_THREAD_INFINITY 1
//#endif
#ifdef SDK_FINALROM
// define if callTrace system not used
#define OS_NO_CALLTRACE
#endif
#ifndef SDK_THREAD_INFINITY
//---- maximum number of thread
#define OS_THREAD_MAX_NUM 16 // changed 8 to 16 (2004/5/26)
#endif
//---- priority of thread that calls osInitThread()
#define OS_THREAD_LAUNCHER_PRIORITY 16
//---- range of thread priority
#define OS_THREAD_PRIORITY_MIN 0
#define OS_THREAD_PRIORITY_MAX 31
//----------------------------------------------------------------------------
typedef struct _OSThread OSThread;
#ifdef SDK_THREAD_INFINITY
typedef struct _OSThreadQueue OSThreadQueue;
typedef struct _OSThreadLink OSThreadLink;
typedef struct _OSMutexQueue OSMutexQueue;
typedef struct _OSMutexLink OSMutexLink;
typedef struct OSMutex OSMutex;
#endif
typedef struct OSiAlarm OSAlarm;
#ifdef SDK_THREAD_INFINITY
struct _OSThreadQueue
{
OSThread *head;
OSThread *tail;
};
struct _OSThreadLink
{
OSThread *prev;
OSThread *next;
};
struct _OSMutexQueue
{
OSMutex *head;
OSMutex *tail;
};
struct _OSMutexLink
{
OSMutex *next;
OSMutex *prev;
};
#endif
//---------------- Thread status
typedef enum
{
OS_THREAD_STATE_WAITING = 0,
OS_THREAD_STATE_READY = 1,
OS_THREAD_STATE_TERMINATED = 2
}
OSThreadState;
#ifndef SDK_THREAD_INFINITY
//---------------- thread queue
#if ( OS_THREAD_MAX_NUM <= 16 )
typedef u16 OSThreadQueue;
#define OS_SIZEOF_OSTHREADQUEUE 16
#elif ( OS_THREAD_MAX_NUM <= 32 )
typedef u32 OSThreadQueue;
#define OS_SIZEOF_OSTHREADQUEUE 32
#else
Error:no bit field any more
#endif
#endif
#define OS_THREAD_SPECIFIC_MAX 3
typedef void (*OSThreadDestructor) (void *);
//---------------- Thread structure
struct _OSThread
{
OSContext context;
OSThreadState state;
OSThread *next;
u32 id;
u32 priority;
void *profiler;
#ifdef SDK_THREAD_INFINITY
OSThreadQueue *queue;
OSThreadLink link;
#endif
#ifndef SDK_THREAD_INFINITY
void *mutex;
void *mutexQueueHead;
void *mutexQueueTail;
#else
OSMutex *mutex; // OSMutex
OSMutexQueue mutexQueue; // OSMutexQueue
#endif
u32 stackTop; // for stack overflow
u32 stackBottom; // for stack underflow
u32 stackWarningOffset;
#ifndef SDK_THREAD_INFINITY
OSThreadQueue joinQueue; // for wakeup threads in thread termination
#if OS_SIZEOF_OSTHREADQUEUE == 16
u16 padding;
#endif
#else
OSThreadQueue joinQueue;
void *specific[OS_THREAD_SPECIFIC_MAX]; // for internal use
OSAlarm *alarmForSleep; // OSAlarm for sleeping
OSThreadDestructor destructor; // thread destructor
void *userParameter; // for user
int systemErrno;
#endif
};
//---------------- Thread & context packed structure
typedef struct OSThreadInfo
{
u16 isNeedRescheduling;
#ifndef SDK_THREAD_INFINITY
u16 max_entry;
u16 irqDepth;
u16 padding;
#else
u16 irqDepth;
#endif
OSThread *current;
OSThread *list;
void *switchCallback; // type: OSSwitchThreadCallback
#ifndef SDK_THREAD_INFINITY
OSThread *entry[OS_THREAD_MAX_NUM];
#endif
}
OSThreadInfo;
// offset
#ifndef SDK_THREAD_INFINITY
#define OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING 0
#define OS_THREADINFO_OFFSET_MAX_ENTRY 2
#define OS_THREADINFO_OFFSET_IRQDEPTH 4
#define OS_THREADINFO_OFFSET_PADDING 6
#define OS_THREADINFO_OFFSET_CURRENT 8
#define OS_THREADINFO_OFFSET_LIST 12
#define OS_THREADINFO_OFFSET_SWITCHCALLBACK 16
#define OS_THREADINFO_OFFSET_ENTRY 20
#else // ifndef SDK_THREAD_INFINITY
#define OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING 0
#define OS_THREADINFO_OFFSET_IRQDEPTH 2
#define OS_THREADINFO_OFFSET_CURRENT 4
#define OS_THREADINFO_OFFSET_LIST 8
#define OS_THREADINFO_OFFSET_SWITCHCALLBACK 12
#define OS_THREADINFO_OFFSET_ENTRY 16
#endif
//---------------- CONTEXT OFFSET
#define OS_THREAD_OFFSET_CONTEXT 0
#define OS_THREAD_OFFSET_STATE (sizeof(OSContext))
#define OS_THREAD_OFFSET_NEXT (sizeof(OSContext)+sizeof(OSThreadState))
#define OS_THREAD_OFFSET_ID (OS_THREAD_OFFSET_NEXT+sizeof(OSThread*))
//---------------- thread stack overflow status
typedef enum
{
OS_STACK_NO_ERROR = 0,
OS_STACK_OVERFLOW = 1,
OS_STACK_ABOUT_TO_OVERFLOW = 2,
OS_STACK_UNDERFLOW = 3
}
OSStackStatus;
//---------------- thread switch callback
typedef void (*OSSwitchThreadCallback) (OSThread *from, OSThread *to);
//---------------- thread resource
typedef struct OSThreadResource
{
int num;
}
OSThreadResource;
//----------------------------------------------------------------------------
//---- private function ( don't use these i_os* function )
void i_osCheckStack(const char *file, int line, const OSThread *thread);
u32 i_osGetSystemStackPointer(void);
u32 i_osGetCurrentStackPointer(void);
OSThread *i_osGetIdleThread(void);
/*---------------------------------------------------------------------------*
Name: osInitThread
Description: Initialize Thread System
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void osInitThread(void);
/*---------------------------------------------------------------------------*
Name: osIsThreadAvailable
Description: check if thread system is available
Arguments: None
Returns: TRUE if available, FALSE if not
*---------------------------------------------------------------------------*/
BOOL osIsThreadAvailable(void);
/*---------------------------------------------------------------------------*
Name: osCreateThread
Description: Create a new Thread
Arguments: thread pointer of thread structure
func function to start thread
arg argument for func
stack stack bottom address
stackSize stack size (byte. must be aligned by 4)
prio thread priority
Returns: None
*---------------------------------------------------------------------------*/
void osCreateThread(OSThread *thread,
void (*func) (void *), void *arg, void *stack, u32 stackSize, u32 prio);
/*---------------------------------------------------------------------------*
Name: osExitThread
Description: Exit thread
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void osExitThread(void);
/*---------------------------------------------------------------------------*
Name: osDestroyThread
Description: destroy specified thread.
Arguments: thread: thread to be destroyed
Returns: None
*---------------------------------------------------------------------------*/
void osDestroyThread(OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osKillThread
Description: switch PC to thread destructor to finalize thread
Arguments: thread : thread to wait to finish
flag : argument for destructor
Returns: None
*---------------------------------------------------------------------------*/
#ifdef SDK_THREAD_INFINITY
void osKillThread(OSThread *thread, void *arg);
void osKillThreadWithPriority(OSThread *thread, void *arg, u32 prio);
#endif
/*---------------------------------------------------------------------------*
Name: osJoinThread
Description: wait for specified thread to terminated
Arguments: thread : thraead to wait to finish
Returns: None
*---------------------------------------------------------------------------*/
void osJoinThread(OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osIsThreadTeminated
Description: check thread status whether it's terminated
Arguments: thread : pointer to thread to be examined
Returns: TRUE if the thread is terminated. FALSE if not
*---------------------------------------------------------------------------*/
BOOL osIsThreadTerminated(const OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osSelectThread
Description: Select thread to execute
Arguments: None
Returns: thread to execute
*---------------------------------------------------------------------------*/
OSThread *osSelectThread(void);
/*---------------------------------------------------------------------------*
Name: osRescheduleThread
Description: do rescheduling threads
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void osRescheduleThread(void);
/*---------------------------------------------------------------------------*
Name: osYieldThread
Description: do thread rescheduling. current thread relinquish CPU
to give chance of running to other threads which has same
priority.
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
extern void osYieldThread(void);
/*---------------------------------------------------------------------------*
Name: osSleepThread
Description: sleep current thread
Arguments: thread Thread queue
Returns: None
*---------------------------------------------------------------------------*/
void osSleepThread(OSThreadQueue *queue);
/*---------------------------------------------------------------------------*
Name: osWakeupThread
Description: wake up threads by queue
Arguments: queue Thread queue
Returns: None
*---------------------------------------------------------------------------*/
void osWakeupThread(OSThreadQueue *queue);
/*---------------------------------------------------------------------------*
Name: osWakeupThreadDirect
Description: wake up thread by specifying thread directly
Arguments: thread Thread to wake up
Returns: None
*---------------------------------------------------------------------------*/
void osWakeupThreadDirect(OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osDumpThreadList
Description: Dump All Thread Infomation (for DEBUG)
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void osDumpThreadList(void);
/*---------------------------------------------------------------------------*
Name: osGetNumberOfThread
Description: Get number of thread which exists in system
Arguments: None
Returns: number of thread which exists in system
*---------------------------------------------------------------------------*/
int osGetNumberOfThread(void);
/*==== static inlie functions ====*/
/*---------------------------------------------------------------------------*
Name: osGetThreadInfo
Description: Get pointer of system thread info structure.
Arguments: None
Returns: pointer of thread info structure
*---------------------------------------------------------------------------*/
extern OSThreadInfo i_osThreadInfo;
static inline OSThreadInfo *osGetThreadInfo(void)
{
return &i_osThreadInfo;
}
/*---------------------------------------------------------------------------*
Name: osGetMaxThreadId
Description: Gets Max id number of available thread number
Arguments: None
Returns: Max id of available thread number
*---------------------------------------------------------------------------*/
static inline u32 osGetMaxThreadId(void)
{
#ifndef SDK_THREAD_INFINITY
return osGetThreadInfo()->max_entry;
#else
return 0x7fffffff; // (=maximin number of int)
#endif
}
/*---------------------------------------------------------------------------*
Name: osGetThread
Description: Gets pointer to thread which id is specified
Arguments: id : thread id to get thread
Returns: pointer to thread which id is specified
*---------------------------------------------------------------------------*/
#ifndef SDK_THREAD_INFINITY
static inline OSThread *osGetThread(u32 id)
{
SDK_ASSERTMSG(id < OS_THREAD_MAX_NUM, "Thread id illegal\n");
return osGetThreadInfo()->entry[id];
}
#else
extern OSThread *osGetThread(u32 id);
#endif
/*---------------------------------------------------------------------------*
Name: osGetThreadId
Description: Gets id of specified thread
Arguments: thread pointer to thread
Returns: id of specified thread
*---------------------------------------------------------------------------*/
static inline u32 osGetThreadId(const OSThread *thread)
{
SDK_ASSERTMSG(thread, "null thread pointer.");
return thread->id;
}
/*---------------------------------------------------------------------------*
Name: osGetThreadState
Description: Gets state of specified thread
Arguments: thread pointer to thread
Returns: state of specified thead
*---------------------------------------------------------------------------*/
static inline OSThreadState osGetThreadState(const OSThread *thread)
{
SDK_ASSERTMSG(thread, "null thread pointer.");
return thread->state;
}
/*---------------------------------------------------------------------------*
Name: osGetThreadContext
Description: Gets pointer to context of specified thread
Arguments: thread pointer to thread
Returns: pointer to context of specified thread
*---------------------------------------------------------------------------*/
static inline OSContext *osGetThreadContext(const OSThread *thread)
{
SDK_ASSERTMSG(thread, "null thread pointer.");
return (OSContext *)&thread->context;
}
/*---------------------------------------------------------------------------*
Name: osIsThreadRunnable
Description: Check if thread is runnable
Arguments: thread pointer to thread
Returns: non zero if thread is runnable
*---------------------------------------------------------------------------*/
static inline BOOL osIsThreadRunnable(const OSThread *thread)
{
return thread->state == OS_THREAD_STATE_READY;
}
/*---------------------------------------------------------------------------*
Name: osInitThreadQueue
Description: Initialize thread queue
Arguments: queue pointer to thread queue
Returns: None
*---------------------------------------------------------------------------*/
static inline void osInitThreadQueue(OSThreadQueue *queue)
{
#ifndef SDK_THREAD_INFINITY
*queue = 0;
#else
queue->head = queue->tail = NULL;
#endif
}
/*---------------------------------------------------------------------------*
Name: osGetCurrentThread
Description: Gets pointer to the current thread
Arguments: None
Returns: Pointer to the current thread
*---------------------------------------------------------------------------*/
static inline OSThread *osGetCurrentThread(void)
{
return osGetThreadInfo()->current;
}
/*---------------------------------------------------------------------------*
Name: osSetCurrentThread
Description: Saves pointer to the current thread
Arguments: thread : thread to be current thread
Returns: Pointer to the current thread
*---------------------------------------------------------------------------*/
static inline void osSetCurrentThread(OSThread *thread)
{
osGetThreadInfo()->current = thread;
}
/*==== stack check ====*/
/*---------------------------------------------------------------------------*
Name: osSetThreadStackWarningOffset
Description: Set warning level for stack checker
Arguments: thread thread to set
offset offset from stack top. must be multiple of 4
Returns: None
*---------------------------------------------------------------------------*/
void osSetThreadStackWarningOffset(OSThread *thread, u32 offset);
/*---------------------------------------------------------------------------*
Name: osGetStackStatus
Description: check thread stack. check each CheckNUM.
return result.
Arguments: thread thread checked
Returns: 0 no error
OS_STACK_OVERFLOW overflow
OS_STACK_ABOUT_TO_OVERFLOW about to overflow
OS_STACK_UNDERFLOW underflow
*---------------------------------------------------------------------------*/
OSStackStatus osGetStackStatus(const OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osCheckStack
Description: check thread stack. check each CheckNum.
if changed, display warning and halt.
Arguments: thread thread to check stack
Returns: None.
( if error occurred, never return )
*---------------------------------------------------------------------------*/
#if !defined(SDK_FINALROM) && !defined(SDK_NO_MESSAGE)
#define osCheckStack( thread ) i_osCheckStack( __FILE__, __LINE__, (const OSThread*)thread );
#else
#define osCheckStack( thread ) ((void)0)
#endif
/*---------------------------------------------------------------------------*
Name: osSetThreadPriority
Description: change priority of thread
Arguments: thread thread to set priority
prio new priority to be set
Returns: TRUE if success
*---------------------------------------------------------------------------*/
BOOL osSetThreadPriority(OSThread *thread, u32 prio);
/*---------------------------------------------------------------------------*
Name: osGetThreadPriority
Description: get priority of thread
Arguments: thread thread to get priority
Returns: priority
*---------------------------------------------------------------------------*/
u32 osGetThreadPriority(const OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osSleep
Description: sleep specified period
Arguments: msec sleeping period. ( milliseconds )
Returns: None.
*---------------------------------------------------------------------------*/
void osSleep(u32 msec);
/*---------------------------------------------------------------------------*
Name: osSetSwitchThreadCallback
Description: set callback called at switching thread
Arguments: callback callback function
Returns: previous callback function before set callback now
*---------------------------------------------------------------------------*/
OSSwitchThreadCallback osSetSwitchThreadCallback(OSSwitchThreadCallback callback);
// notice: substans is in os_callTrace.c.
// define here because of OSThread declaration.
/*---------------------------------------------------------------------------*
Name: osDumpThreadCallTrace
Description: dump callStack of thread
Arguments: thread : thread
Returns: None
*---------------------------------------------------------------------------*/
void osDumpThreadCallTrace(const OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osDisableScheduler
Description: disable scheduler
Arguments: None
Returns: Previous scheduler suspend count.
Suspended if value >= 0.
*---------------------------------------------------------------------------*/
u32 osDisableScheduler(void);
/*---------------------------------------------------------------------------*
Name: osEnableScheduler
Description: enable scheduler
Arguments: None
Returns: Previous scheduler suspend count.
Suspended if value >= 0.
*---------------------------------------------------------------------------*/
u32 osEnableScheduler(void);
#ifdef SDK_THREAD_INFINITY
/*---------------------------------------------------------------------------*
Name: osSetThreadDestructor
Description: set thread destructor, which is called when that thread exits.
Arguments: thread : thread pointer
dtor : destructor function
Returns: None
*---------------------------------------------------------------------------*/
void osSetThreadDestructor(OSThread *thread, OSThreadDestructor dtor);
/*---------------------------------------------------------------------------*
Name: osGetThreadDestructor
Description: get thread destructor which is set
Arguments: thread : thread pointer
Returns: destructor function
*---------------------------------------------------------------------------*/
OSThreadDestructor osGetThreadDestructor(const OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osSetThreadParameter
Description: set user parameter which is allowed to use freely.
Arguments: thread : thread pointer
parameter : user parameter
Returns: None
*---------------------------------------------------------------------------*/
void osSetThreadParameter(OSThread *thread, void *parameter);
/*---------------------------------------------------------------------------*
Name: osGetThreadParameter
Description: get user parameter which is set
Arguments: thread : thread pointer
Returns: user parameter which is set
*---------------------------------------------------------------------------*/
void *osGetThreadParameter(const OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osGetErrno
Description: get system error number.
Arguments: None.
Returns: error number
*---------------------------------------------------------------------------*/
int osGetErrno(void);
#endif
/*---------------------------------------------------------------------------*
Name: osIsThreadInList
Description: check if the specified thread is in the thread list
Arguments: thread : thread
Returns: TRUE if thread is in the thread list
*---------------------------------------------------------------------------*/
BOOL osIsThreadInList(const OSThread *thread);
/*---------------------------------------------------------------------------*
Name: osSetThreadDestructorStack
Description: specify stack area to call thread destructor
Arguments: stack stack bottom address
Returns: None
*---------------------------------------------------------------------------*/
void osSetThreadDestructorStack(void *stack);
#ifdef SDK_THREAD_INFINITY
//================================================================================
// The following functions are for internal use. Not for user.
//================================================================================
/*---------------------------------------------------------------------------*
Name: i_osRemoveMutexLinkFromQueue
Description: remove mutex from mutex queue
Arguments: queue : mutex queue
Returns: mutex pointer which is removed
*---------------------------------------------------------------------------*/
extern OSMutex *i_osRemoveMutexLinkFromQueue(OSMutexQueue * queue);
/*---------------------------------------------------------------------------*
Name: i_osSetSystemErrno
Description: set system error number.
Arguments: thread : thread to set error number
errno : error number to set
Returns: None
*---------------------------------------------------------------------------*/
void i_osSetSystemErrno(OSThread *thread, int errno);
/*---------------------------------------------------------------------------*
Name: i_osGetSystemErrno
Description: get system error number.
Arguments: thread : thread to set error number
Returns: error number
*---------------------------------------------------------------------------*/
int i_osGetSystemErrno(const OSThread *thread);
#define OSi_SPECIFIC_CPS 0
/*---------------------------------------------------------------------------*
Name: i_osSetSpecificData
Description: set system specific data
Arguments: thread : thread to set data
index : index of specific array
data : data to set
Returns: None
*---------------------------------------------------------------------------*/
static inline void i_osSetSpecificData(OSThread *thread, int index, void *data)
{
SDK_ASSERT(thread && 0 <= index && index < OS_THREAD_SPECIFIC_MAX);
thread->specific[index] = data;
}
/*---------------------------------------------------------------------------*
Name: i_osGetSpecificData
Description: get system specific data
Arguments: thread : thread to get data
index : index of specific array
Returns: error number
*---------------------------------------------------------------------------*/
static inline void *i_osGetSpecificData(const OSThread *thread, int index)
{
SDK_ASSERT(thread && 0 <= index && index < OS_THREAD_SPECIFIC_MAX);
return thread->specific[index];
}
#endif
//================================================================================
// The following functions are for operations of thread struct.
// use carefully.
//================================================================================
/*---------------------------------------------------------------------------*
Name: osGetThreadList
Description: get first thread of thread list.
Arguments: None
Returns: first thread of thread list
*---------------------------------------------------------------------------*/
static inline OSThread *osGetThreadList(void)
{
return osGetThreadInfo()->list;
}
/*---------------------------------------------------------------------------*
Name: osGetNextThread
Description: get thread which is linked next in thread list
Arguments: thread : thread to get next thread
Returns: next thread. NULL means no next thread ( specified thread may be last )
*---------------------------------------------------------------------------*/
static inline OSThread *osGetNextThread(const OSThread *thread)
{
SDK_ASSERT(thread);
return thread->next;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
/* BROM_OS_THREAD_H_ */
#endif