Commit | Line | Data |
---|---|---|
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 |
14 | typedef 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 | ||
23 | typedef uint32_t pthread_t; | |
24 | typedef int pthread_attr_t; | |
679b71e2 | 25 | |
31f52a9f JW |
26 | typedef LightLock pthread_mutex_t; |
27 | typedef int pthread_mutexattr_t; | |
28 | ||
29 | typedef uint32_t pthread_cond_t; | |
679b71e2 JW |
30 | typedef int pthread_condattr_t; |
31 | ||
31f52a9f JW |
32 | #endif |
33 | ||
fc99395c | 34 | static 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 | ||
49 | static 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 | ||
62 | static inline void pthread_exit(void *retval) | |
63 | { | |
64 | (void)retval; | |
65 | ||
93c24a56 | 66 | threadExit(0); |
fc99395c | 67 | } |
68 | ||
679b71e2 JW |
69 | static inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { |
70 | LightLock_Init(mutex); | |
71 | return 0; | |
72 | } | |
73 | ||
74 | static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { | |
75 | LightLock_Lock(mutex); | |
76 | return 0; | |
77 | } | |
78 | ||
79 | static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { | |
80 | LightLock_Unlock(mutex); | |
81 | return 0; | |
82 | } | |
83 | ||
84 | static inline int pthread_mutex_destroy(pthread_mutex_t *mutex) { | |
85 | return 0; | |
86 | } | |
87 | ||
88 | static 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 | ||
108 | static 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 | ||
120 | static 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 | ||
131 | static 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 |