From 52f00833b0b38129b6d887617112d978e1d9ee29 Mon Sep 17 00:00:00 2001
From: Francisco Javier Trujillo Mata <[EMAIL REDACTED]>
Date: Mon, 13 Jun 2022 20:58:18 +0200
Subject: [PATCH] Add Thread drivers
---
CMakeLists.txt | 6 ++
include/SDL_config.h.cmake | 1 +
src/thread/SDL_thread_c.h | 2 +
src/thread/ps2/SDL_syssem.c | 159 +++++++++++++++++++++++++++++++
src/thread/ps2/SDL_systhread.c | 140 +++++++++++++++++++++++++++
src/thread/ps2/SDL_systhread_c.h | 24 +++++
6 files changed, 332 insertions(+)
create mode 100644 src/thread/ps2/SDL_syssem.c
create mode 100644 src/thread/ps2/SDL_systhread.c
create mode 100644 src/thread/ps2/SDL_systhread_c.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d27fa084bcb..e1e1dfc76c5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2524,6 +2524,12 @@ elseif(PSP)
elseif(PS2)
list(APPEND EXTRA_CFLAGS "-DPS2")
+ if(SDL_THREADS)
+ set(SDL_THREAD_PS2 1)
+ file(GLOB PS2_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_sysmutex.c ${SDL2_SOURCE_DIR}/src/thread/ps2/*.c)
+ set(SOURCE_FILES ${SOURCE_FILES} ${PS2_THREAD_SOURCES})
+ set(HAVE_SDL_THREADS TRUE)
+ endif()
if(SDL_TIMERS)
set(SDL_TIMER_PS2 1)
file(GLOB PS2_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/ps2/*.c)
diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake
index 5d476194cb5..7048dcdd3f5 100644
--- a/include/SDL_config.h.cmake
+++ b/include/SDL_config.h.cmake
@@ -378,6 +378,7 @@
#cmakedefine SDL_THREAD_OS2 @SDL_THREAD_OS2@
#cmakedefine SDL_THREAD_VITA @SDL_THREAD_VITA@
#cmakedefine SDL_THREAD_PSP @SDL_THREAD_PSP@
+#cmakedefine SDL_THREAD_PS2 @SDL_THREAD_PS2@
/* Enable various timer systems */
#cmakedefine SDL_TIMER_HAIKU @SDL_TIMER_HAIKU@
diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h
index b4df526d1cc..55a4a8875d4 100644
--- a/src/thread/SDL_thread_c.h
+++ b/src/thread/SDL_thread_c.h
@@ -32,6 +32,8 @@
#include "pthread/SDL_systhread_c.h"
#elif SDL_THREAD_WINDOWS
#include "windows/SDL_systhread_c.h"
+#elif SDL_THREAD_PS2
+#include "ps2/SDL_systhread_c.h"
#elif SDL_THREAD_PSP
#include "psp/SDL_systhread_c.h"
#elif SDL_THREAD_VITA
diff --git a/src/thread/ps2/SDL_syssem.c b/src/thread/ps2/SDL_syssem.c
new file mode 100644
index 00000000000..e6b0aee2558
--- /dev/null
+++ b/src/thread/ps2/SDL_syssem.c
@@ -0,0 +1,159 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_THREAD_PS2
+
+/* Semaphore functions for the PS2. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <timer_alarm.h>
+
+#include "SDL_error.h"
+#include "SDL_thread.h"
+
+#include <kernel.h>
+
+struct SDL_semaphore {
+ s32 semid;
+};
+
+static void usercb(struct timer_alarm_t *alarm, void *arg) {
+ iReleaseWaitThread((int)arg);
+}
+
+/* Create a semaphore */
+SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
+{
+ SDL_sem *sem;
+ ee_sema_t sema;
+
+ sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
+ if (sem != NULL) {
+ /* TODO: Figure out the limit on the maximum value. */
+ sema.init_count = initial_value;
+ sema.max_count = 255;
+ sema.option = 0;
+ sem->semid = CreateSema(&sema);
+
+ if (sem->semid < 0) {
+ SDL_SetError("Couldn't create semaphore");
+ SDL_free(sem);
+ sem = NULL;
+ }
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return sem;
+}
+
+/* Free the semaphore */
+void SDL_DestroySemaphore(SDL_sem *sem)
+{
+ if (sem != NULL) {
+ if (sem->semid > 0) {
+ DeleteSema(sem->semid);
+ sem->semid = 0;
+ }
+
+ SDL_free(sem);
+ }
+}
+
+int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
+{
+ int ret;
+ struct timer_alarm_t alarm;
+ InitializeTimerAlarm(&alarm);
+
+ if (sem == NULL) {
+ SDL_InvalidParamError("sem");
+ return 0;
+ }
+
+ if (timeout == 0) {
+ if (PollSema(sem->semid) < 0) {
+ return SDL_MUTEX_TIMEDOUT;
+ }
+ return 0;
+ }
+
+ if (timeout != SDL_MUTEX_MAXWAIT) {
+ SetTimerAlarm(&alarm, MSec2TimerBusClock(timeout), &usercb, (void *)GetThreadId());
+ }
+
+ ret = WaitSema(sem->semid);
+ StopTimerAlarm(&alarm);
+
+ if (ret < 0)
+ return SDL_MUTEX_TIMEDOUT;
+ return 0; //Wait condition satisfied.
+}
+
+int SDL_SemTryWait(SDL_sem *sem)
+{
+ return SDL_SemWaitTimeout(sem, 0);
+}
+
+int SDL_SemWait(SDL_sem *sem)
+{
+ return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
+}
+
+/* Returns the current count of the semaphore */
+Uint32 SDL_SemValue(SDL_sem *sem)
+{
+ ee_sema_t info;
+
+ if (sem == NULL) {
+ SDL_InvalidParamError("sem");
+ return 0;
+ }
+
+ if (ReferSemaStatus(sem->semid, &info) >= 0) {
+ return info.count;
+ }
+
+ return 0;
+}
+
+int SDL_SemPost(SDL_sem *sem)
+{
+ int res;
+
+ if (sem == NULL) {
+ return SDL_InvalidParamError("sem");
+ }
+
+ res = SignalSema(sem->semid);
+ if (res < 0) {
+ return SDL_SetError("sceKernelSignalSema() failed");
+ }
+
+ return 0;
+}
+
+#endif /* SDL_THREAD_PS2 */
+
+/* vim: ts=4 sw=4
+ */
diff --git a/src/thread/ps2/SDL_systhread.c b/src/thread/ps2/SDL_systhread.c
new file mode 100644
index 00000000000..4df65abf1d1
--- /dev/null
+++ b/src/thread/ps2/SDL_systhread.c
@@ -0,0 +1,140 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_THREAD_PS2
+
+/* PS2 thread management routines for SDL */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "SDL_error.h"
+#include "SDL_thread.h"
+#include "../SDL_systhread.h"
+#include "../SDL_thread_c.h"
+#include <kernel.h>
+
+static void FinishThread(SDL_Thread *thread) {
+ ee_thread_status_t info;
+ int res;
+
+ res = ReferThreadStatus(thread->handle, &info);
+ TerminateThread(thread->handle);
+ DeleteThread(thread->handle);
+ DeleteSema((int)thread->endfunc);
+
+ if (res > 0) {
+ SDL_free(info.stack);
+ }
+}
+
+static int childThread(void *arg)
+{
+ SDL_Thread *thread = (SDL_Thread *)arg;
+ int res = thread->userfunc(thread->userdata);
+ SignalSema((int)thread->endfunc);
+ return res;
+}
+
+int SDL_SYS_CreateThread(SDL_Thread *thread)
+{
+ ee_thread_status_t status;
+ ee_thread_t eethread;
+ ee_sema_t sema;
+ size_t stack_size;
+ int priority = 32;
+
+ /* Set priority of new thread to the same as the current thread */
+ // status.size = sizeof(ee_thread_t);
+ if (ReferThreadStatus(GetThreadId(), &status) == 0) {
+ priority = status.current_priority;
+ }
+
+ stack_size = thread->stacksize ? ((int) thread->stacksize) : 0x1800;
+
+
+ /* Create EE Thread */
+ eethread.attr = 0;
+ eethread.option = 0;
+ eethread.func = &childThread;
+ eethread.stack = SDL_malloc(stack_size);
+ eethread.stack_size = stack_size;
+ eethread.gp_reg = &_gp;
+ eethread.initial_priority = priority;
+ thread->handle = CreateThread(&eethread);
+
+ if (thread->handle < 0) {
+ return SDL_SetError("CreateThread() failed");
+ }
+
+ // Prepare el semaphore for the ending function
+ sema.init_count = 0;
+ sema.max_count = 1;
+ sema.option = 0;
+ thread->endfunc = (void *)CreateSema(&sema);
+
+ return StartThread(thread->handle, thread);
+}
+
+void SDL_SYS_SetupThread(const char *name)
+{
+ /* Do nothing. */
+}
+
+SDL_threadID SDL_ThreadID(void)
+{
+ return (SDL_threadID) GetThreadId();
+}
+
+void SDL_SYS_WaitThread(SDL_Thread *thread)
+{
+ WaitSema((int)thread->endfunc);
+ ReleaseWaitThread(thread->handle);
+ FinishThread(thread);
+}
+
+void SDL_SYS_DetachThread(SDL_Thread *thread)
+{
+ /* Do nothing. */
+}
+
+int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
+{
+ int value;
+
+ if (priority == SDL_THREAD_PRIORITY_LOW) {
+ value = 111;
+ } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
+ value = 32;
+ } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
+ value = 16;
+ } else {
+ value = 50;
+ }
+
+ return ChangeThreadPriority(GetThreadId(),value);
+}
+
+#endif /* SDL_THREAD_PS2 */
+
+/* vim: ts=4 sw=4
+ */
diff --git a/src/thread/ps2/SDL_systhread_c.h b/src/thread/ps2/SDL_systhread_c.h
new file mode 100644
index 00000000000..ffeca76d62f
--- /dev/null
+++ b/src/thread/ps2/SDL_systhread_c.h
@@ -0,0 +1,24 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <stdint.h>
+
+typedef int32_t SYS_ThreadHandle;