Add async CD access
[pcsx_rearmed.git] / frontend / 3ds / pthread.h
index 836f4cb..cc3c965 100644 (file)
@@ -2,41 +2,41 @@
 #ifndef _3DS_PTHREAD_WRAP__
 #define _3DS_PTHREAD_WRAP__
 
-#include "3ds.h"
-#include "stdlib.h"
-#include "string.h"
-#include "stdio.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
 
+#include "3ds_utils.h"
 
 #define CTR_PTHREAD_STACK_SIZE 0x10000
+#define FALSE 0
 
-typedef struct
-{
-   Handle handle;
-   u32* stack;
-}pthread_t;
+typedef int32_t pthread_t;
 typedef int pthread_attr_t;
 
-//#ifndef DEBUG_HOLD
-//#include "stdio.h"
-//void wait_for_input(void);
+typedef LightLock pthread_mutex_t;
+typedef int pthread_mutexattr_t;
+
+typedef struct {
+  uint32_t semaphore;
+  LightLock lock;
+  uint32_t waiting;
+} pthread_cond_t;
 
-//#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0)
-//#endif
+typedef int pthread_condattr_t;
 
 static inline int pthread_create(pthread_t *thread,
       const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)
 {
+   int procnum = -2; // use default cpu
+   bool isNew3DS;
+   APT_CheckNew3DS(&isNew3DS);
 
-//   DEBUG_HOLD();
-
-   thread->stack =  linearMemAlign(CTR_PTHREAD_STACK_SIZE, 8);
+   if (isNew3DS)
+     procnum = 2;
 
-   svcCreateThread(&thread->handle, (ThreadFunc)start_routine,arg,
-                   (u32*)((u32)thread->stack + CTR_PTHREAD_STACK_SIZE),
-                   0x25, 1);
-
-   return 1;
+   *thread = threadCreate(start_routine, arg, CTR_PTHREAD_STACK_SIZE, 0x25, procnum, FALSE);
+   return 0;
 }
 
 
@@ -44,11 +44,10 @@ static inline int pthread_join(pthread_t thread, void **retval)
 {
    (void)retval;
 
-//   DEBUG_HOLD();
-   if(svcWaitSynchronization(thread.handle, INT64_MAX))
+   if(threadJoin(thread, INT64_MAX))
       return -1;
 
-   linearFree(thread.stack);
+   threadFree(thread);
 
    return 0;
 }
@@ -58,11 +57,67 @@ static inline void pthread_exit(void *retval)
 {   
    (void)retval;
 
-//   DEBUG_HOLD();
-   svcExitThread();
+   threadExit(0);
+}
+
+static inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) {
+  LightLock_Init(mutex);
+  return 0;
+}
+
+static inline int pthread_mutex_lock(pthread_mutex_t *mutex) {
+  LightLock_Lock(mutex);
+  return 0;
+}
+
+static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) {
+  LightLock_Unlock(mutex);
+  return 0;
+}
+
+static inline int pthread_mutex_destroy(pthread_mutex_t *mutex) {
+  return 0;
+}
+
+static inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) {
+  if (svcCreateSemaphore(&cond->semaphore, 0, 1))
+    goto error;
+
+  LightLock_Init(&cond->lock);
+  cond->waiting = 0;
+  return 0;
+
+ error:
+  svcCloseHandle(cond->semaphore);
+  return -1;
+}
+
+static inline int pthread_cond_signal(pthread_cond_t *cond) {
+  int32_t count;
+  LightLock_Lock(&cond->lock);
+  if (cond->waiting) {
+    cond->waiting--;
+    svcReleaseSemaphore(&count, cond->semaphore, 1);
+  }
+  LightLock_Unlock(&cond->lock);
+  return 0;
+}
+
+static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *lock) {
+  LightLock_Lock(&cond->lock);
+  cond->waiting++;
+  LightLock_Unlock(lock);
+  LightLock_Unlock(&cond->lock);
+  svcWaitSynchronization(cond->semaphore, INT64_MAX);
+  LightLock_Lock(lock);
+  return 0;
+}
+
+static inline int pthread_cond_destroy(pthread_cond_t *cond) {
+  svcCloseHandle(cond->semaphore);
+  return 0;
 }
 
-//#undef DEBUG_HOLD
 
 #endif //_3DS_PTHREAD_WRAP__