#include "../../SDL_internal.h"
#if SDL_THREAD_PSP
#include <stdio.h>
#include <stdlib.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#include <pspthreadman.h>
#include <pspkerror.h>
struct SDL_semaphore {
SceUID semid;
};
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem;
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
if (sem != NULL) {
sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL);
if (sem->semid < 0) {
SDL_SetError("Couldn't create semaphore");
SDL_free(sem);
sem = NULL;
}
} else {
SDL_OutOfMemory();
}
return sem;
}
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem != NULL) {
if (sem->semid > 0) {
sceKernelDeleteSema(sem->semid);
sem->semid = 0;
}
SDL_free(sem);
}
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
Uint32 *pTimeout;
int res;
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
}
if (timeout == 0) {
res = sceKernelPollSema(sem->semid, 1);
if (res < 0) {
return SDL_MUTEX_TIMEDOUT;
}
return 0;
}
if (timeout == SDL_MUTEX_MAXWAIT) {
pTimeout = NULL;
} else {
timeout *= 1000;
pTimeout = &timeout;
}
res = sceKernelWaitSema(sem->semid, 1, (SceUInt *) pTimeout);
switch (res) {
case SCE_KERNEL_ERROR_OK:
return 0;
case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
return SDL_MUTEX_TIMEDOUT;
default:
return SDL_SetError("sceKernelWaitSema() failed");
}
}
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, 0);
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32 SDL_SemValue(SDL_sem *sem)
{
SceKernelSemaInfo info;
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
}
if (sceKernelReferSemaStatus(sem->semid, &info) >= 0) {
return info.currentCount;
}
return 0;
}
int SDL_SemPost(SDL_sem *sem)
{
int res;
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
res = sceKernelSignalSema(sem->semid, 1);
if (res < 0) {
return SDL_SetError("sceKernelSignalSema() failed");
}
return 0;
}
#endif