-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #109 from Yotona/thread
thread.c
- Loading branch information
Showing
7 changed files
with
267 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,8 @@ | |
|
||
// ... | ||
|
||
void FrameRenderLoop(void*); | ||
|
||
extern u8 g_abRenderLoopStack[0x20000]; | ||
|
||
#endif // FRM_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/** | ||
* @file kernel.h | ||
* | ||
* @brief Control for Semaphores and Threads | ||
*/ | ||
#ifndef KERNEL_H | ||
#define KERNEL_H | ||
|
||
#include "common.h" | ||
|
||
extern "C" { | ||
/** | ||
* @brief Thread parameters for initialization | ||
*/ | ||
struct ThreadParam { | ||
int status; // Thread status | ||
void (*entry)(void *); // Thread entry point | ||
void *stack; // Stack address used by the thread (16-byte aligned) | ||
int stackSize; // Stack size in bytes, must be a multiple of 16 | ||
void *gpReg; // GP register value | ||
int initPriority; // Initial thread priority (1-127). Must be specified when creating a thread | ||
int currentPriority; // Current thread priority | ||
unsigned int attr; // Reserved for system use | ||
unsigned int option; // Reserved for system use | ||
int waitType; // Wait type | ||
int waitId; // Semaphore ID if waitType is "semaphore" | ||
int wakeupCount; // Wakeup request count | ||
}; | ||
|
||
/** | ||
* @brief Semaphore parameters for initialization | ||
*/ | ||
struct SemaParam { | ||
int currentCount; // Current semaphore count | ||
int maxCount; // Maximum semaphore count | ||
int initCount; // Initial semaphore count | ||
int numWaitThreads; // Number of threads waiting on the semaphore | ||
unsigned int attr; // Semaphore attributes | ||
unsigned int option; // Optional user-defined data | ||
}; | ||
|
||
/** | ||
* @brief Create a counting semaphore object. | ||
* | ||
* @details Up to 256 semaphores can be created, 3 of which are reserved during runtime | ||
* initialization by `crt0.s` (2 from `_InitSys` and 1 from `InitThread`). | ||
* | ||
* @param sparam Initial semaphore parameters | ||
* @return Semaphore ID on success, -1 if creation would exceed the maximum number of semaphores | ||
* or a negative value was passed for `sema->initCount` | ||
*/ | ||
int CreateSema(SemaParam *sparam); | ||
|
||
/** | ||
* @brief Get semaphore resource | ||
* | ||
* @param sema Semaphore ID | ||
* @return Semaphore count on success, -1 on failure | ||
*/ | ||
int WaitSema(int sema); | ||
|
||
/** | ||
* @brief Release semaphore resource | ||
* | ||
* @details If the `sid` value is 0 and there is no free space in the semaphore queue, | ||
* the thread at the wait queue start will be released and placed in READY state. | ||
* In all other cases, the value of the semaphore is incremented. | ||
* | ||
* @param sid Semaphore ID | ||
* @return Semaphore ID on success, -1 on failure | ||
*/ | ||
int SignalSema(int sid); | ||
|
||
/** | ||
* @brief Create a new thread | ||
* | ||
* @details The created thread is placed in a DORMANT state and not executed until the thread is started. | ||
* | ||
* @param tparam Initial thread parameters | ||
* | ||
* @return Thread ID on success, -1 on failure | ||
*/ | ||
int CreateThread(struct ThreadParam *tparam); | ||
|
||
/** | ||
* @brief Get the ID of the calling thread. | ||
* | ||
* @return Thread ID | ||
*/ | ||
int GetThreadId(void); | ||
|
||
/** | ||
* @brief Change the priority of a thread | ||
* | ||
* @details The thread will be entered at the end of the ready queue at the corresponding priority. | ||
* The new priority setting will be valid until the thread is terminated or the priority is changed again. | ||
* | ||
* @param tid Thread ID | ||
* @param priority New priority (1-127) | ||
* | ||
* @return The previous priority of the thread on success, -1 on failure | ||
*/ | ||
int ChangeThreadPriority(int tid, int priority); | ||
} | ||
|
||
#endif // KERNEL_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/** | ||
* @file thread.h | ||
* | ||
* @brief Semaphore, Thread, and Critical Section utilities | ||
*/ | ||
#ifndef THREAD_H | ||
#define THREAD_H | ||
|
||
#include "common.h" | ||
|
||
/** | ||
* @brief Details for a critical section | ||
*/ | ||
struct CRITSECT | ||
{ | ||
int cEnter; | ||
int thread; | ||
int sema; | ||
}; | ||
|
||
/** | ||
* @brief Create a semaphore. | ||
* | ||
* @param initCount Initial count. | ||
* @param maxCount Maximum count. | ||
* @return The semaphore ID. | ||
*/ | ||
int SemaCreate(int initCount, int maxCount); | ||
|
||
/** | ||
* @brief Initialize a critical section. | ||
* | ||
* @param pcritsect Critical section. | ||
*/ | ||
void InitCritSect(CRITSECT* pcritsect); | ||
|
||
/** | ||
* @brief Enter a critical section. | ||
* | ||
* @param pcritsect Critical section. | ||
*/ | ||
void EnterCritSect(CRITSECT* pcritsect); | ||
|
||
/** | ||
* @brief Leave a critical section. | ||
* | ||
* @param pcritsect Critical section. | ||
*/ | ||
void LeaveCritSect(CRITSECT* pcritsect); | ||
|
||
/** | ||
* @brief Initialize parameters for a rendering thread. | ||
*/ | ||
void StartupThread(); | ||
|
||
extern CRITSECT g_athread; | ||
|
||
#endif // THREAD_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include "common.h" | ||
#include <sce/kernel.h> | ||
#include <sce/memset.h> | ||
#include <frm.h> | ||
#include <thread.h> | ||
|
||
int SemaCreate(int initCount, int maxCount) | ||
{ | ||
SemaParam sp; | ||
|
||
memset(&sp, 0, sizeof(SemaParam)); | ||
sp.initCount = initCount; | ||
sp.maxCount = maxCount; | ||
return CreateSema(&sp); | ||
} | ||
|
||
INCLUDE_ASM(const s32, "P2/thread", func_001E22B8); | ||
|
||
void InitCritSect(CRITSECT *pcritsect) | ||
{ | ||
pcritsect->thread = -1; | ||
pcritsect->sema = SemaCreate(1, 1); | ||
} | ||
|
||
void EnterCritSect(CRITSECT *pcritsect) | ||
{ | ||
int threadId = GetThreadId(); | ||
|
||
if (threadId != pcritsect->thread) | ||
{ | ||
WaitSema(pcritsect->sema); | ||
pcritsect->thread = threadId; | ||
pcritsect->cEnter = 1; | ||
} | ||
else | ||
{ | ||
pcritsect->cEnter++; | ||
} | ||
} | ||
|
||
void LeaveCritSect(CRITSECT *pcritsect) | ||
{ | ||
int critSects = pcritsect->cEnter - 1; | ||
pcritsect->cEnter = critSects; | ||
|
||
if (critSects == 0) { | ||
pcritsect->thread = -1; | ||
SignalSema(pcritsect->sema); | ||
} | ||
} | ||
|
||
INCLUDE_ASM(const s32, "P2/thread", func_001E2390); | ||
|
||
void StartupThread() | ||
{ | ||
ThreadParam tp; | ||
|
||
g_athread.cEnter = GetThreadId(); | ||
ChangeThreadPriority(g_athread.cEnter, 4); | ||
memset(&tp, 0, sizeof(ThreadParam)); | ||
|
||
tp.stackSize = 0x20000; | ||
tp.stack = g_abRenderLoopStack; | ||
tp.initPriority = 2; | ||
tp.gpReg = &_gpReg; | ||
tp.entry = FrameRenderLoop; | ||
|
||
g_athread.thread = CreateThread(&tp); | ||
} |