mirror of
https://github.com/TheOnlyZac/sly1.git
synced 2024-11-26 23:20:43 +00:00
thread.c
This commit is contained in:
parent
79ff104c06
commit
bc3cadd56a
@ -277,8 +277,8 @@ segments:
|
||||
#- [0x, asm, P2/target]
|
||||
|
||||
- [0xe18f8, asm, P2/text]
|
||||
#- [0x, asm, P2/thread]
|
||||
#- [0x, asm, P2/tn]
|
||||
- [0xe3268, c, P2/thread]
|
||||
- [0xe3420, asm, P2/tn]
|
||||
|
||||
- [0xe5e38, c, P2/transition]
|
||||
- [0xe6378, asm, P2/turret]
|
||||
|
@ -4,6 +4,8 @@ _exit = 0x1000B8; // type:func
|
||||
__builtin_delete = 0x18d778; // type:func
|
||||
memcmp = 0x1F59C4; // type:func
|
||||
|
||||
_gpReg = 0x2832F0;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Unknown file
|
||||
// Related to save files
|
||||
@ -1069,6 +1071,19 @@ DecrementSwHandsOff__FP2SW = 0x1dda50; // type:func
|
||||
g_psw = 0x275710; // size:0x4
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// P2/thread.c
|
||||
////////////////////////////////////////////////////////////////
|
||||
SemaCreate__Fii = 0x1e2268; // type:func
|
||||
InitCritSect__FP8CRITSECT = 0x1e22c0; // type:func
|
||||
EnterCritSect__FP8CRITSECT = 0x1e22f8; // type:func
|
||||
LeaveCritSect__FP8CRITSECT = 0x1e2358; // type:func
|
||||
StartupThread__Fv = 0x1e2398; // type:func
|
||||
|
||||
g_athread = 0x275958; // size:0xC
|
||||
|
||||
g_abRenderLoopStack = 0x6056d0; // size:0x20000
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// P2/transition.c
|
||||
////////////////////////////////////////////////////////////////
|
||||
@ -1220,6 +1235,17 @@ sceCdBreak = 0x203e28; // type:func
|
||||
sceClose = 0x1f8c38; // type:func
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// sce/klib.c
|
||||
////////////////////////////////////////////////////////////////
|
||||
CreateThread = 0x1F6A10; // type:func
|
||||
ChangeThreadPriority = 0x1F6A50; // type:func
|
||||
GetThreadId = 0x1F6A90; // type:func
|
||||
CreateSema = 0x1F6B20; // type:func
|
||||
SignalSema = 0x1F6B40; // type:func
|
||||
WaitSema = 0x1F6B60; // type:func
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// sce/rand.c
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "types.h"
|
||||
#include "vtables.h"
|
||||
|
||||
extern int _gpReg; // Global pointer register
|
||||
|
||||
/**
|
||||
* @brief RGBA color value.
|
||||
*/
|
||||
|
@ -10,4 +10,8 @@
|
||||
|
||||
// ...
|
||||
|
||||
void FrameRenderLoop(void*);
|
||||
|
||||
extern u8 g_abRenderLoopStack[0x20000];
|
||||
|
||||
#endif // FRM_H
|
||||
|
100
include/sce/kernel.h
Normal file
100
include/sce/kernel.h
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @file kernel.h
|
||||
*
|
||||
* @brief Control for Semaphores and Threads
|
||||
*/
|
||||
#ifndef KERNEL_H
|
||||
#define KERNEL_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
extern "C" {
|
||||
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
|
||||
};
|
||||
|
||||
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
|
55
include/thread.h
Normal file
55
include/thread.h
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file thread.h
|
||||
*
|
||||
* @brief Thread and critical section utilities
|
||||
*/
|
||||
#ifndef THREAD_H
|
||||
#define THREAD_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
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
|
69
src/P2/thread.c
Normal file
69
src/P2/thread.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include "common.h"
|
||||
#include <sce/kernel.h>
|
||||
#include <sce/memset.h>
|
||||
#include <thread.h>
|
||||
#include <frm.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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user