Skip to content

Commit

Permalink
Merge pull request #109 from Yotona/thread
Browse files Browse the repository at this point in the history
thread.c
  • Loading branch information
TheOnlyZac authored Nov 10, 2024
2 parents 79ff104 + 7163b30 commit 14f2cb5
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 2 deletions.
4 changes: 2 additions & 2 deletions config/sly1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
26 changes: 26 additions & 0 deletions config/symbol_addrs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -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
////////////////////////////////////////////////////////////////
Expand Down
2 changes: 2 additions & 0 deletions include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "types.h"
#include "vtables.h"

extern int _gpReg; // Global pointer register

/**
* @brief RGBA color value.
*/
Expand Down
4 changes: 4 additions & 0 deletions include/frm.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@

// ...

void FrameRenderLoop(void*);

extern u8 g_abRenderLoopStack[0x20000];

#endif // FRM_H
106 changes: 106 additions & 0 deletions include/sce/kernel.h
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
58 changes: 58 additions & 0 deletions include/thread.h
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
69 changes: 69 additions & 0 deletions src/P2/thread.c
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);
}

0 comments on commit 14f2cb5

Please sign in to comment.