Skip to content

Commit

Permalink
Use PSP variant psp1
Browse files Browse the repository at this point in the history
System functions on PSP are very sensitive to where stack is.
So let system functions handle it
  • Loading branch information
phcoder committed Apr 27, 2020
1 parent 06b4cdc commit ed059b2
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
6 changes: 4 additions & 2 deletions libco/libco.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ void genode_free_secondary_stack(void *stack);
#include "ppc.c"
#elif defined(__aarch64__)
#include "aarch64.c"
#elif defined(__mips__)
#include "mips.c"
#elif defined PSP
#include "psp1.c"
#elif defined VITA
#include "scefiber.c"
#elif defined(__mips__)
#include "mips.c"
#elif defined(__ARM_EABI__) || defined(__arm__)
#include "armeabi.c"
#else
Expand Down
45 changes: 45 additions & 0 deletions libco/psp1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#define LIBCO_C
#include "libco.h"

#include <stdlib.h>
#include <pspthreadman.h>

/* Since cothread_t is a void pointer it must contain an address. We can't return a reference to a local variable
* because it would go out of scope, so we create a static variable instead so we can return a reference to it.
*/
static SceUID active_thread_id = 0;

cothread_t co_active()
{
active_thread_id = sceKernelGetThreadId();
return &active_thread_id;
}

cothread_t co_create(unsigned int size, void (*entrypoint)(void))
{
/* Similar scenario as with active_thread_id except there will only be one active_thread_id while there could be many
* new threads each with their own handle, so we create them on the heap instead and delete them manually when they're
* no longer needed in co_delete().
*/
cothread_t handle = malloc(sizeof(cothread_t));

/* SceKernelThreadEntry has a different signature than entrypoint, but in practice this seems to work */
SceUID new_thread_id = sceKernelCreateThread("cothread", (SceKernelThreadEntry)entrypoint, 0x12, size, 0, NULL);
sceKernelStartThread(new_thread_id, 0, NULL);

*(SceUID *)handle = new_thread_id;
return handle;
}

void co_delete(cothread_t handle)
{
sceKernelTerminateDeleteThread(*(SceUID *)handle);
free(handle);
}

void co_switch(cothread_t handle)
{
sceKernelWakeupThread(*(SceUID *)handle);
/* Sleep the currently active thread so the new thread can start */
sceKernelSleepThread();
}

0 comments on commit ed059b2

Please sign in to comment.