[3DS] Support latest libctru
[pcsx_rearmed.git] / frontend / 3ds / pthread.h
CommitLineData
fc99395c 1
2#ifndef _3DS_PTHREAD_WRAP__
3#define _3DS_PTHREAD_WRAP__
4
f72db18e 5#include <stdlib.h>
6#include <string.h>
7#include <stdio.h>
fc99395c 8
f72db18e 9#include "3ds_utils.h"
fc99395c 10
37c2f059 11#define CTR_PTHREAD_STACK_SIZE 0x10000
679b71e2 12#define FALSE 0
fc99395c 13
679b71e2
JW
14typedef struct {
15 uint32_t semaphore;
16 LightLock lock;
17 uint32_t waiting;
31f52a9f
JW
18} cond_t;
19
20#if !defined(PTHREAD_SCOPE_PROCESS)
21/* An earlier version of devkitARM does not define the pthread types. Can remove in r54+. */
22
23typedef uint32_t pthread_t;
24typedef int pthread_attr_t;
679b71e2 25
31f52a9f
JW
26typedef LightLock pthread_mutex_t;
27typedef int pthread_mutexattr_t;
28
29typedef uint32_t pthread_cond_t;
679b71e2
JW
30typedef int pthread_condattr_t;
31
31f52a9f
JW
32#endif
33
fc99395c 34static inline int pthread_create(pthread_t *thread,
35 const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)
36{
679b71e2
JW
37 int procnum = -2; // use default cpu
38 bool isNew3DS;
39 APT_CheckNew3DS(&isNew3DS);
40
41 if (isNew3DS)
42 procnum = 2;
43
44 *thread = threadCreate(start_routine, arg, CTR_PTHREAD_STACK_SIZE, 0x25, procnum, FALSE);
45 return 0;
fc99395c 46}
47
48
49static inline int pthread_join(pthread_t thread, void **retval)
50{
51 (void)retval;
52
93c24a56 53 if(threadJoin(thread, INT64_MAX))
fc99395c 54 return -1;
55
93c24a56 56 threadFree(thread);
fc99395c 57
58 return 0;
59}
60
61
62static inline void pthread_exit(void *retval)
63{
64 (void)retval;
65
93c24a56 66 threadExit(0);
fc99395c 67}
68
679b71e2
JW
69static inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) {
70 LightLock_Init(mutex);
71 return 0;
72}
73
74static inline int pthread_mutex_lock(pthread_mutex_t *mutex) {
75 LightLock_Lock(mutex);
76 return 0;
77}
78
79static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) {
80 LightLock_Unlock(mutex);
81 return 0;
82}
83
84static inline int pthread_mutex_destroy(pthread_mutex_t *mutex) {
85 return 0;
86}
87
88static inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) {
31f52a9f
JW
89 cond_t *cond_data = calloc(1, sizeof(cond_t));
90 if (!cond_data)
679b71e2
JW
91 goto error;
92
31f52a9f
JW
93 if (svcCreateSemaphore(&cond_data->semaphore, 0, 1))
94 goto error;
95
96 LightLock_Init(&cond_data->lock);
97 cond_data->waiting = 0;
98 *cond = cond_data;
679b71e2
JW
99 return 0;
100
101 error:
31f52a9f
JW
102 svcCloseHandle(cond_data->semaphore);
103 if (cond_data)
104 free(cond_data);
679b71e2
JW
105 return -1;
106}
107
108static inline int pthread_cond_signal(pthread_cond_t *cond) {
109 int32_t count;
31f52a9f
JW
110 cond_t *cond_data = (cond_t *)*cond;
111 LightLock_Lock(&cond_data->lock);
112 if (cond_data->waiting) {
113 cond_data->waiting--;
114 svcReleaseSemaphore(&count, cond_data->semaphore, 1);
679b71e2 115 }
31f52a9f 116 LightLock_Unlock(&cond_data->lock);
679b71e2
JW
117 return 0;
118}
119
120static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *lock) {
31f52a9f
JW
121 cond_t *cond_data = (cond_t *)*cond;
122 LightLock_Lock(&cond_data->lock);
123 cond_data->waiting++;
679b71e2 124 LightLock_Unlock(lock);
31f52a9f
JW
125 LightLock_Unlock(&cond_data->lock);
126 svcWaitSynchronization(cond_data->semaphore, INT64_MAX);
679b71e2
JW
127 LightLock_Lock(lock);
128 return 0;
129}
130
131static inline int pthread_cond_destroy(pthread_cond_t *cond) {
31f52a9f
JW
132 if (*cond) {
133 cond_t *cond_data = (cond_t *)*cond;
134
135 svcCloseHandle(cond_data->semaphore);
136 free(*cond);
137 }
138 *cond = 0;
679b71e2
JW
139 return 0;
140}
141
fc99395c 142
143#endif //_3DS_PTHREAD_WRAP__
144