mirror of https://github.com/ClassiCube/ClassiCube
Split up Gamecube and Wii backends more
This commit is contained in:
parent
1cdc87082f
commit
119cacac0d
|
|
@ -253,6 +253,10 @@ void Thread_Join(void* handle) {
|
||||||
threadFree(thread);
|
threadFree(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
LightLock* lock = (LightLock*)Mem_Alloc(1, sizeof(LightLock), "mutex");
|
LightLock* lock = (LightLock*)Mem_Alloc(1, sizeof(LightLock), "mutex");
|
||||||
LightLock_Init(lock);
|
LightLock_Init(lock);
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,14 @@ void Thread_Join(void* handle) {
|
||||||
thread_id thread = (thread_id)handle;
|
thread_id thread = (thread_id)handle;
|
||||||
wait_for_thread(thread, NULL);
|
wait_for_thread(thread, NULL);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
// NOTE: BeOS only, as haiku uses the more efficient pthreads implementation in Platform_Posix.c
|
||||||
|
#if defined CC_BUILD_BEOS
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
sem_id id = create_sem(1, name);
|
sem_id id = create_sem(1, name);
|
||||||
return (void*)id;
|
return (void*)id;
|
||||||
|
|
|
||||||
|
|
@ -389,6 +389,10 @@ void Thread_Join(void* handle) {
|
||||||
Thread_Detach(handle);
|
Thread_Detach(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
||||||
InitializeCriticalSection(ptr);
|
InitializeCriticalSection(ptr);
|
||||||
|
|
|
||||||
|
|
@ -452,6 +452,10 @@ void Thread_Join(void* handle) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
||||||
InitializeCriticalSection(ptr);
|
InitializeCriticalSection(ptr);
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,10 @@ void Thread_Join(void* handle) {
|
||||||
Thread_Detach(handle);
|
Thread_Detach(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
||||||
InitializeCriticalSection(ptr);
|
InitializeCriticalSection(ptr);
|
||||||
|
|
|
||||||
|
|
@ -513,6 +513,10 @@ void Thread_Join(void* handle) {
|
||||||
thd_join((kthread_t*)handle, NULL);
|
thd_join((kthread_t*)handle, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
mutex_t* ptr = (mutex_t*)Mem_Alloc(1, sizeof(mutex_t), "mutex");
|
mutex_t* ptr = (mutex_t*)Mem_Alloc(1, sizeof(mutex_t), "mutex");
|
||||||
int res = mutex_init(ptr, MUTEX_TYPE_NORMAL);
|
int res = mutex_init(ptr, MUTEX_TYPE_NORMAL);
|
||||||
|
|
|
||||||
|
|
@ -1,73 +1,3 @@
|
||||||
/*########################################################################################################################*
|
|
||||||
*------------------------------------------------------Logging/Time-------------------------------------------------------*
|
|
||||||
*#########################################################################################################################*/
|
|
||||||
#ifdef HW_RVL
|
|
||||||
static void LogOverEXI(char* msg, int len) {
|
|
||||||
u32 cmd = 0x80000000 | (0x800400 << 6); // write flag, UART base address
|
|
||||||
|
|
||||||
// https://hitmen.c02.at/files/yagcd/yagcd/chap10.html
|
|
||||||
// Try to acquire "MASK ROM"/"IPL" link
|
|
||||||
// Writing to the IPL is used for debug message logging
|
|
||||||
if (EXI_Lock(EXI_CHANNEL_0, EXI_DEVICE_1, NULL) == 0) return;
|
|
||||||
if (EXI_Select(EXI_CHANNEL_0, EXI_DEVICE_1, EXI_SPEED8MHZ) == 0) {
|
|
||||||
EXI_Unlock(EXI_CHANNEL_0); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXI_Imm( EXI_CHANNEL_0, &cmd, 4, EXI_WRITE, NULL);
|
|
||||||
EXI_Sync( EXI_CHANNEL_0);
|
|
||||||
EXI_ImmEx( EXI_CHANNEL_0, msg, len, EXI_WRITE);
|
|
||||||
EXI_Deselect(EXI_CHANNEL_0);
|
|
||||||
EXI_Unlock( EXI_CHANNEL_0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Platform_Log(const char* msg, int len) {
|
|
||||||
char tmp[256 + 1];
|
|
||||||
len = min(len, 256);
|
|
||||||
// See EXI_DeviceIPL.cpp in Dolphin, \r is what triggers buffered message to be logged
|
|
||||||
Mem_Copy(tmp, msg, len); tmp[len] = '\r';
|
|
||||||
|
|
||||||
LogOverEXI(tmp, len + 1);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void Platform_Log(const char* msg, int len) {
|
|
||||||
SYS_Report("%.*s\n", len, msg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TimeMS DateTime_CurrentUTC(void) {
|
|
||||||
struct timeval cur;
|
|
||||||
gettimeofday(&cur, NULL);
|
|
||||||
return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DateTime_CurrentLocal(struct cc_datetime* t) {
|
|
||||||
struct timeval cur;
|
|
||||||
struct tm loc_time;
|
|
||||||
gettimeofday(&cur, NULL);
|
|
||||||
localtime_r(&cur.tv_sec, &loc_time);
|
|
||||||
|
|
||||||
t->year = loc_time.tm_year + 1900;
|
|
||||||
t->month = loc_time.tm_mon + 1;
|
|
||||||
t->day = loc_time.tm_mday;
|
|
||||||
t->hour = loc_time.tm_hour;
|
|
||||||
t->minute = loc_time.tm_min;
|
|
||||||
t->second = loc_time.tm_sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_uint64 Stopwatch_Measure(void) {
|
|
||||||
#ifdef HW_RVL
|
|
||||||
return SYS_Time();
|
|
||||||
#else
|
|
||||||
return __SYS_GetSystemTime();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
|
||||||
if (end < beg) return 0;
|
|
||||||
return ticks_to_microsecs(end - beg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*-------------------------------------------------------Crash handling----------------------------------------------------*
|
*-------------------------------------------------------Crash handling----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
|
@ -246,145 +176,6 @@ void Thread_Join(void* handle) {
|
||||||
Mem_Free(ptr);
|
Mem_Free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Mutex_Create(const char* name) {
|
|
||||||
mutex_t* ptr = (mutex_t*)Mem_Alloc(1, sizeof(mutex_t), "mutex");
|
|
||||||
int res = LWP_MutexInit(ptr, false);
|
|
||||||
if (res) Process_Abort2(res, "Creating mutex");
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex_Free(void* handle) {
|
|
||||||
mutex_t* mutex = (mutex_t*)handle;
|
|
||||||
int res = LWP_MutexDestroy(*mutex);
|
|
||||||
if (res) Process_Abort2(res, "Destroying mutex");
|
|
||||||
Mem_Free(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex_Lock(void* handle) {
|
|
||||||
mutex_t* mutex = (mutex_t*)handle;
|
|
||||||
int res = LWP_MutexLock(*mutex);
|
|
||||||
if (res) Process_Abort2(res, "Locking mutex");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex_Unlock(void* handle) {
|
|
||||||
mutex_t* mutex = (mutex_t*)handle;
|
|
||||||
int res = LWP_MutexUnlock(*mutex);
|
|
||||||
if (res) Process_Abort2(res, "Unlocking mutex");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HW_RVL
|
|
||||||
// should really use a semaphore with max 1.. too bad no 'TimedWait' though
|
|
||||||
struct WaitData {
|
|
||||||
cond_t cond;
|
|
||||||
mutex_t mutex;
|
|
||||||
int signalled; // For when Waitable_Signal is called before Waitable_Wait
|
|
||||||
};
|
|
||||||
|
|
||||||
void* Waitable_Create(const char* name) {
|
|
||||||
struct WaitData* ptr = (struct WaitData*)Mem_Alloc(1, sizeof(struct WaitData), "waitable");
|
|
||||||
int res;
|
|
||||||
|
|
||||||
res = LWP_CondInit(&ptr->cond);
|
|
||||||
if (res) Process_Abort2(res, "Creating waitable");
|
|
||||||
res = LWP_MutexInit(&ptr->mutex, false);
|
|
||||||
if (res) Process_Abort2(res, "Creating waitable mutex");
|
|
||||||
|
|
||||||
ptr->signalled = false;
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Waitable_Free(void* handle) {
|
|
||||||
struct WaitData* ptr = (struct WaitData*)handle;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
res = LWP_CondDestroy(ptr->cond);
|
|
||||||
if (res) Process_Abort2(res, "Destroying waitable");
|
|
||||||
res = LWP_MutexDestroy(ptr->mutex);
|
|
||||||
if (res) Process_Abort2(res, "Destroying waitable mutex");
|
|
||||||
Mem_Free(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Waitable_Signal(void* handle) {
|
|
||||||
struct WaitData* ptr = (struct WaitData*)handle;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
Mutex_Lock(&ptr->mutex);
|
|
||||||
ptr->signalled = true;
|
|
||||||
Mutex_Unlock(&ptr->mutex);
|
|
||||||
|
|
||||||
res = LWP_CondSignal(ptr->cond);
|
|
||||||
if (res) Process_Abort2(res, "Signalling event");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Waitable_Wait(void* handle) {
|
|
||||||
struct WaitData* ptr = (struct WaitData*)handle;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
Mutex_Lock(&ptr->mutex);
|
|
||||||
if (!ptr->signalled) {
|
|
||||||
res = LWP_CondWait(ptr->cond, ptr->mutex);
|
|
||||||
if (res) Process_Abort2(res, "Waitable wait");
|
|
||||||
}
|
|
||||||
ptr->signalled = false;
|
|
||||||
Mutex_Unlock(&ptr->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
|
||||||
struct WaitData* ptr = (struct WaitData*)handle;
|
|
||||||
struct timespec ts;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
ts.tv_sec = milliseconds / TB_MSPERSEC;
|
|
||||||
ts.tv_nsec = (milliseconds % TB_MSPERSEC) * TB_NSPERMS;
|
|
||||||
|
|
||||||
Mutex_Lock(&ptr->mutex);
|
|
||||||
if (!ptr->signalled) {
|
|
||||||
res = LWP_CondTimedWait(ptr->cond, ptr->mutex, &ts);
|
|
||||||
if (res && res != ETIMEDOUT) Process_Abort2(res, "Waitable wait for");
|
|
||||||
}
|
|
||||||
ptr->signalled = false;
|
|
||||||
Mutex_Unlock(&ptr->mutex);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void* Waitable_Create(const char* name) {
|
|
||||||
sem_t* ptr = (sem_t*)Mem_Alloc(1, sizeof(sem_t), "waitable");
|
|
||||||
int res = LWP_SemInit(ptr, 0, 1);
|
|
||||||
if (res) Process_Abort2(res, "Creating waitable");
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Waitable_Free(void* handle) {
|
|
||||||
sem_t* ptr = (sem_t*)handle;
|
|
||||||
int res = LWP_SemDestroy(*ptr);
|
|
||||||
if (res) Process_Abort2(res, "Destroying waitable");
|
|
||||||
Mem_Free(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Waitable_Signal(void* handle) {
|
|
||||||
sem_t* ptr = (sem_t*)handle;
|
|
||||||
int res = LWP_SemPost(*ptr);
|
|
||||||
if (res && res != EOVERFLOW) Process_Abort2(res, "Signalling event");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Waitable_Wait(void* handle) {
|
|
||||||
sem_t* ptr = (sem_t*)handle;
|
|
||||||
int res = LWP_SemWait(*ptr);
|
|
||||||
if (res) Process_Abort2(res, "Event wait");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
|
||||||
sem_t* ptr = (sem_t*)handle;
|
|
||||||
struct timespec ts;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
ts.tv_sec = milliseconds / TB_MSPERSEC;
|
|
||||||
ts.tv_nsec = (milliseconds % TB_MSPERSEC) * TB_NSPERMS;
|
|
||||||
|
|
||||||
res = LWP_SemTimedWait(*ptr, &ts);
|
|
||||||
if (res && res != ETIMEDOUT) Process_Abort2(res, "Event timed wait");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,43 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*------------------------------------------------------Logging/Time-------------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
void Platform_Log(const char* msg, int len) {
|
||||||
|
SYS_Report("%.*s\n", len, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeMS DateTime_CurrentUTC(void) {
|
||||||
|
struct timeval cur;
|
||||||
|
gettimeofday(&cur, NULL);
|
||||||
|
return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateTime_CurrentLocal(struct cc_datetime* t) {
|
||||||
|
struct timeval cur;
|
||||||
|
struct tm loc_time;
|
||||||
|
gettimeofday(&cur, NULL);
|
||||||
|
localtime_r(&cur.tv_sec, &loc_time);
|
||||||
|
|
||||||
|
t->year = loc_time.tm_year + 1900;
|
||||||
|
t->month = loc_time.tm_mon + 1;
|
||||||
|
t->day = loc_time.tm_mday;
|
||||||
|
t->hour = loc_time.tm_hour;
|
||||||
|
t->minute = loc_time.tm_min;
|
||||||
|
t->second = loc_time.tm_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_uint64 Stopwatch_Measure(void) {
|
||||||
|
return __SYS_GetSystemTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
||||||
|
if (end < beg) return 0;
|
||||||
|
return ticks_to_microsecs(end - beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
|
@ -133,6 +170,74 @@ static void InitSockets(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
void* Mutex_Create(const char* name) {
|
||||||
|
mutex_t* ptr = (mutex_t*)Mem_Alloc(1, sizeof(mutex_t), "mutex");
|
||||||
|
int res = LWP_MutexInit(ptr, false);
|
||||||
|
if (res) Process_Abort2(res, "Creating mutex");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Free(void* handle) {
|
||||||
|
mutex_t* mutex = (mutex_t*)handle;
|
||||||
|
int res = LWP_MutexDestroy(*mutex);
|
||||||
|
if (res) Process_Abort2(res, "Destroying mutex");
|
||||||
|
Mem_Free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Lock(void* handle) {
|
||||||
|
mutex_t* mutex = (mutex_t*)handle;
|
||||||
|
int res = LWP_MutexLock(*mutex);
|
||||||
|
if (res) Process_Abort2(res, "Locking mutex");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Unlock(void* handle) {
|
||||||
|
mutex_t* mutex = (mutex_t*)handle;
|
||||||
|
int res = LWP_MutexUnlock(*mutex);
|
||||||
|
if (res) Process_Abort2(res, "Unlocking mutex");
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Waitable_Create(const char* name) {
|
||||||
|
sem_t* ptr = (sem_t*)Mem_Alloc(1, sizeof(sem_t), "waitable");
|
||||||
|
int res = LWP_SemInit(ptr, 0, 1);
|
||||||
|
if (res) Process_Abort2(res, "Creating waitable");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Free(void* handle) {
|
||||||
|
sem_t* ptr = (sem_t*)handle;
|
||||||
|
int res = LWP_SemDestroy(*ptr);
|
||||||
|
if (res) Process_Abort2(res, "Destroying waitable");
|
||||||
|
Mem_Free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Signal(void* handle) {
|
||||||
|
sem_t* ptr = (sem_t*)handle;
|
||||||
|
int res = LWP_SemPost(*ptr);
|
||||||
|
if (res && res != EOVERFLOW) Process_Abort2(res, "Signalling event");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Wait(void* handle) {
|
||||||
|
sem_t* ptr = (sem_t*)handle;
|
||||||
|
int res = LWP_SemWait(*ptr);
|
||||||
|
if (res) Process_Abort2(res, "Event wait");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||||
|
sem_t* ptr = (sem_t*)handle;
|
||||||
|
struct timespec ts;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
ts.tv_sec = milliseconds / TB_MSPERSEC;
|
||||||
|
ts.tv_nsec = (milliseconds % TB_MSPERSEC) * TB_NSPERMS;
|
||||||
|
|
||||||
|
res = LWP_SemTimedWait(*ptr, &ts);
|
||||||
|
if (res && res != ETIMEDOUT) Process_Abort2(res, "Event timed wait");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*-------------------------------------------------------Encryption--------------------------------------------------------*
|
*-------------------------------------------------------Encryption--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,66 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*------------------------------------------------------Logging/Time-------------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static void LogOverEXI(char* msg, int len) {
|
||||||
|
u32 cmd = 0x80000000 | (0x800400 << 6); // write flag, UART base address
|
||||||
|
|
||||||
|
// https://hitmen.c02.at/files/yagcd/yagcd/chap10.html
|
||||||
|
// Try to acquire "MASK ROM"/"IPL" link
|
||||||
|
// Writing to the IPL is used for debug message logging
|
||||||
|
if (EXI_Lock(EXI_CHANNEL_0, EXI_DEVICE_1, NULL) == 0) return;
|
||||||
|
if (EXI_Select(EXI_CHANNEL_0, EXI_DEVICE_1, EXI_SPEED8MHZ) == 0) {
|
||||||
|
EXI_Unlock(EXI_CHANNEL_0); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXI_Imm( EXI_CHANNEL_0, &cmd, 4, EXI_WRITE, NULL);
|
||||||
|
EXI_Sync( EXI_CHANNEL_0);
|
||||||
|
EXI_ImmEx( EXI_CHANNEL_0, msg, len, EXI_WRITE);
|
||||||
|
EXI_Deselect(EXI_CHANNEL_0);
|
||||||
|
EXI_Unlock( EXI_CHANNEL_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_Log(const char* msg, int len) {
|
||||||
|
char tmp[256 + 1];
|
||||||
|
len = min(len, 256);
|
||||||
|
// See EXI_DeviceIPL.cpp in Dolphin, \r is what triggers buffered message to be logged
|
||||||
|
Mem_Copy(tmp, msg, len); tmp[len] = '\r';
|
||||||
|
|
||||||
|
LogOverEXI(tmp, len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeMS DateTime_CurrentUTC(void) {
|
||||||
|
struct timeval cur;
|
||||||
|
gettimeofday(&cur, NULL);
|
||||||
|
return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateTime_CurrentLocal(struct cc_datetime* t) {
|
||||||
|
struct timeval cur;
|
||||||
|
struct tm loc_time;
|
||||||
|
gettimeofday(&cur, NULL);
|
||||||
|
localtime_r(&cur.tv_sec, &loc_time);
|
||||||
|
|
||||||
|
t->year = loc_time.tm_year + 1900;
|
||||||
|
t->month = loc_time.tm_mon + 1;
|
||||||
|
t->day = loc_time.tm_mday;
|
||||||
|
t->hour = loc_time.tm_hour;
|
||||||
|
t->minute = loc_time.tm_min;
|
||||||
|
t->second = loc_time.tm_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_uint64 Stopwatch_Measure(void) {
|
||||||
|
return SYS_Time();
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
||||||
|
if (end < beg) return 0;
|
||||||
|
return ticks_to_microsecs(end - beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
|
@ -119,6 +179,109 @@ static void InitSockets(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
void* Mutex_Create(const char* name) {
|
||||||
|
mutex_t* ptr = (mutex_t*)Mem_Alloc(1, sizeof(mutex_t), "mutex");
|
||||||
|
int res = LWP_MutexInit(ptr, false);
|
||||||
|
if (res) Process_Abort2(res, "Creating mutex");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Free(void* handle) {
|
||||||
|
mutex_t* mutex = (mutex_t*)handle;
|
||||||
|
int res = LWP_MutexDestroy(*mutex);
|
||||||
|
if (res) Process_Abort2(res, "Destroying mutex");
|
||||||
|
Mem_Free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Lock(void* handle) {
|
||||||
|
mutex_t* mutex = (mutex_t*)handle;
|
||||||
|
int res = LWP_MutexLock(*mutex);
|
||||||
|
if (res) Process_Abort2(res, "Locking mutex");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Unlock(void* handle) {
|
||||||
|
mutex_t* mutex = (mutex_t*)handle;
|
||||||
|
int res = LWP_MutexUnlock(*mutex);
|
||||||
|
if (res) Process_Abort2(res, "Unlocking mutex");
|
||||||
|
}
|
||||||
|
|
||||||
|
// should really use a semaphore with max 1.. too bad no 'TimedWait' though
|
||||||
|
struct WaitData {
|
||||||
|
cond_t cond;
|
||||||
|
mutex_t mutex;
|
||||||
|
int signalled; // For when Waitable_Signal is called before Waitable_Wait
|
||||||
|
};
|
||||||
|
|
||||||
|
void* Waitable_Create(const char* name) {
|
||||||
|
struct WaitData* ptr = (struct WaitData*)Mem_Alloc(1, sizeof(struct WaitData), "waitable");
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = LWP_CondInit(&ptr->cond);
|
||||||
|
if (res) Process_Abort2(res, "Creating waitable");
|
||||||
|
res = LWP_MutexInit(&ptr->mutex, false);
|
||||||
|
if (res) Process_Abort2(res, "Creating waitable mutex");
|
||||||
|
|
||||||
|
ptr->signalled = false;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Free(void* handle) {
|
||||||
|
struct WaitData* ptr = (struct WaitData*)handle;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = LWP_CondDestroy(ptr->cond);
|
||||||
|
if (res) Process_Abort2(res, "Destroying waitable");
|
||||||
|
res = LWP_MutexDestroy(ptr->mutex);
|
||||||
|
if (res) Process_Abort2(res, "Destroying waitable mutex");
|
||||||
|
Mem_Free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Signal(void* handle) {
|
||||||
|
struct WaitData* ptr = (struct WaitData*)handle;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
Mutex_Lock(&ptr->mutex);
|
||||||
|
ptr->signalled = true;
|
||||||
|
Mutex_Unlock(&ptr->mutex);
|
||||||
|
|
||||||
|
res = LWP_CondSignal(ptr->cond);
|
||||||
|
if (res) Process_Abort2(res, "Signalling event");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Wait(void* handle) {
|
||||||
|
struct WaitData* ptr = (struct WaitData*)handle;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
Mutex_Lock(&ptr->mutex);
|
||||||
|
if (!ptr->signalled) {
|
||||||
|
res = LWP_CondWait(ptr->cond, ptr->mutex);
|
||||||
|
if (res) Process_Abort2(res, "Waitable wait");
|
||||||
|
}
|
||||||
|
ptr->signalled = false;
|
||||||
|
Mutex_Unlock(&ptr->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||||
|
struct WaitData* ptr = (struct WaitData*)handle;
|
||||||
|
struct timespec ts;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
ts.tv_sec = milliseconds / TB_MSPERSEC;
|
||||||
|
ts.tv_nsec = (milliseconds % TB_MSPERSEC) * TB_NSPERMS;
|
||||||
|
|
||||||
|
Mutex_Lock(&ptr->mutex);
|
||||||
|
if (!ptr->signalled) {
|
||||||
|
res = LWP_CondTimedWait(ptr->cond, ptr->mutex, &ts);
|
||||||
|
if (res && res != ETIMEDOUT) Process_Abort2(res, "Waitable wait for");
|
||||||
|
}
|
||||||
|
ptr->signalled = false;
|
||||||
|
Mutex_Unlock(&ptr->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*-------------------------------------------------------Encryption--------------------------------------------------------*
|
*-------------------------------------------------------Encryption--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
|
|
||||||
|
|
@ -413,6 +413,10 @@ void Thread_Detach(void* handle) {
|
||||||
void Thread_Join(void* handle) {
|
void Thread_Join(void* handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,10 @@ void Thread_Join(void* handle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
ee_sema_t sema = { 0 };
|
ee_sema_t sema = { 0 };
|
||||||
sema.init_count = 1;
|
sema.init_count = 1;
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,10 @@ void Thread_Join(void* handle) {
|
||||||
Mem_Free(thread);
|
Mem_Free(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
sys_mutex_attr_t attr;
|
sys_mutex_attr_t attr;
|
||||||
sysMutexAttrInitialize(attr);
|
sysMutexAttrInitialize(attr);
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,10 @@ void Thread_Join(void* handle) {
|
||||||
Mem_Free(ptr);
|
Mem_Free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
pthread_mutex_t* ptr = (pthread_mutex_t*)Mem_Alloc(1, sizeof(pthread_mutex_t), "mutex");
|
pthread_mutex_t* ptr = (pthread_mutex_t*)Mem_Alloc(1, sizeof(pthread_mutex_t), "mutex");
|
||||||
int res = pthread_mutex_init(ptr, NULL);
|
int res = pthread_mutex_init(ptr, NULL);
|
||||||
|
|
|
||||||
|
|
@ -270,6 +270,10 @@ void Thread_Join(void* handle) {
|
||||||
sceKernelDeleteThread((int)handle);
|
sceKernelDeleteThread((int)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
SceLwMutexWorkarea* ptr = (SceLwMutexWorkarea*)Mem_Alloc(1, sizeof(SceLwMutexWorkarea), "mutex");
|
SceLwMutexWorkarea* ptr = (SceLwMutexWorkarea*)Mem_Alloc(1, sizeof(SceLwMutexWorkarea), "mutex");
|
||||||
int res = sceKernelCreateLwMutex(ptr, name, 0, 0, NULL);
|
int res = sceKernelCreateLwMutex(ptr, name, 0, 0, NULL);
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,10 @@ void Thread_Join(void* handle) {
|
||||||
sceKernelDeleteThread((int)handle);
|
sceKernelDeleteThread((int)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
SceKernelLwMutexWork* ptr = (SceKernelLwMutexWork*)Mem_Alloc(1, sizeof(SceKernelLwMutexWork), "mutex");
|
SceKernelLwMutexWork* ptr = (SceKernelLwMutexWork*)Mem_Alloc(1, sizeof(SceKernelLwMutexWork), "mutex");
|
||||||
int res = sceKernelCreateLwMutex(ptr, name, 0, 0, NULL);
|
int res = sceKernelCreateLwMutex(ptr, name, 0, 0, NULL);
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,10 @@ void Thread_Join(void* handle) {
|
||||||
Mem_Free(ptr);
|
Mem_Free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
RMutex* mutex = new RMutex;
|
RMutex* mutex = new RMutex;
|
||||||
if (!mutex) Process_Abort("Creating mutex");
|
if (!mutex) Process_Abort("Creating mutex");
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,10 @@ void Thread_Join(void* handle) {
|
||||||
OSJoinThread((OSThread*)handle, &result);
|
OSJoinThread((OSThread*)handle, &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
OSFastMutex* mutex = (OSFastMutex*)Mem_Alloc(1, sizeof(OSFastMutex), "mutex");
|
OSFastMutex* mutex = (OSFastMutex*)Mem_Alloc(1, sizeof(OSFastMutex), "mutex");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,10 @@ void Thread_Join(void* handle) {
|
||||||
Thread_Detach(handle);
|
Thread_Detach(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
||||||
RtlInitializeCriticalSection(ptr);
|
RtlInitializeCriticalSection(ptr);
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,10 @@ void Thread_Detach(void* handle) {// TODO
|
||||||
void Thread_Join(void* handle) {// TODO
|
void Thread_Join(void* handle) {// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Synchronisation-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void* Mutex_Create(const char* name) {
|
void* Mutex_Create(const char* name) {
|
||||||
return Mem_AllocCleared(1, sizeof(int), "mutex");
|
return Mem_AllocCleared(1, sizeof(int), "mutex");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue