polar-objc 5.44
An Objective-C runtime library
Loading...
Searching...
No Matches
polar-windows-platform-threading.c
1/* Internal API: low-level Windows threading routines for polar-objc.
2 Copyright (C) 2022-2025 Michael Malicoat <[email protected]>
3
4 This file is part of polar-objc.
5
6 polar-objc is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
8
9 polar-objc is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
10 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11 details.
12
13 You should have received a copy of the GNU General Public License along with this program; see the file LICENSE. If
14 not, see <http://www.gnu.org/licenses/>.
15*/
16
17
18// Public ==============================================================================================================
19
23
24// Condition variables -------------------------------------------------------------------------------------------------
25
26POLAR_FUNCTION_INTERNAL intptr_t
27cnd_init( cnd_t *p_cond )
28{
29 assert( p_cond != NULL );
30
31 p_cond->event_condition = CreateEvent(NULL, NO, NO, NULL);
32 if( p_cond->event_condition != (HANDLE)0 )
33 return mtx_init( &p_cond->lock_condition, mtx_recursive );
34
35 else
36 return -1;
37}
38
39POLAR_FUNCTION_INTERNAL void
41{
42 HANDLE event_condition;
43
44 if( p_cond != NULL )
45 ;
46
47 else
48 return;
49
50 assert( p_cond->count_waiters == 0 );
51
52 if( p_cond->event_condition != (HANDLE)0 )
53 {
54 mtx_lock( &p_cond->lock_condition );
55
56 event_condition = p_cond->event_condition;
57 p_cond->event_condition = (HANDLE)0;
58
59 mtx_unlock( &p_cond->lock_condition );
60 mtx_destroy( &p_cond->lock_condition );
61
62 CloseHandle(event_condition);
63 }
64}
65
66POLAR_FUNCTION_INTERNAL intptr_t
68{
69 HANDLE event_condition;
70 intptr_t count_waiters;
71
72 assert( p_cond != NULL );
73
74 mtx_lock( &p_cond->lock_condition );
75
76 event_condition = p_cond->event_condition;
77 count_waiters = p_cond->count_waiters;
78 p_cond->count_waiters = 0;
79
80 mtx_unlock( &p_cond->lock_condition );
81
82 if( event_condition != (HANDLE)0 )
83 {
84 for( ; count_waiters > 0; count_waiters-- )
85 {
86 // According to Microsoft, this releases exactly one thread at a time when used with an auto-reset event
87 if( SetEvent(event_condition) )
88 ;
89
90 else
91 return -1;
92 }
93
94 return 0;
95 }
96
97 else
98 return -1;
99}
100
101POLAR_FUNCTION_INTERNAL intptr_t
103{
104 intptr_t result;
105
106 assert( p_cond != NULL );
107
108 result = -1;
109
110 mtx_lock( &p_cond->lock_condition );
111
112 if( p_cond->event_condition != (HANDLE)0 )
113 {
114 if( p_cond->count_waiters > 0 )
115 {
116 if( SetEvent(p_cond->event_condition) )
117 {
118 p_cond->count_waiters--;
119 result = 0;
120 }
121 }
122
123 else
124 result = 0;
125 }
126
127 mtx_unlock( &p_cond->lock_condition );
128
129 return result;
130}
131
132POLAR_FUNCTION_INTERNAL intptr_t
133cnd_wait( cnd_t *p_cond, mtx_t *p_mutex )
134{
135 HANDLE event_condition;
136
137 assert( p_cond != NULL );
138
139 mtx_lock( &p_cond->lock_condition );
140
141 event_condition = p_cond->event_condition;
142 if( event_condition != (HANDLE)0 )
143 {
144 p_cond->count_waiters++;
145 mtx_unlock(p_mutex);
146 }
147
148 mtx_unlock( &p_cond->lock_condition );
149
150 if( (event_condition != (HANDLE)0) && (WaitForSingleObject(event_condition, INFINITE) == WAIT_OBJECT_0) )
151 return mtx_lock(p_mutex);
152
153 else
154 return -1;
155}
156
157// Threading -----------------------------------------------------------------------------------------------------------
158
159POLAR_FUNCTION_INTERNAL intptr_t
160thrd_create( thrd_t *out_thread_id, thrd_start_t thread_func, void *thread_data )
161{
162 HANDLE handle_thread_new;
163
164 assert( out_thread_id != NULL );
165 assert( thread_func != NULL );
166
167 *out_thread_id = (thrd_t)0;
168
169 handle_thread_new = CreateThread(NULL, 0, thread_func, thread_data, 0, out_thread_id);
170 if( handle_thread_new != (HANDLE)0 )
171 return 0;
172
173 else
174 return -1;
175}
176
177POLAR_FUNCTION_INTERNAL intptr_t
178thrd_join( thrd_t id_thread_target, intptr_t *__p_retval_unused OBJC_IGNORE_UNUSED )
179{
180 intptr_t result;
181 HANDLE handle_thread_target;
182
183 result = -1;
184
185 handle_thread_target = OpenThread(SYNCHRONIZE, NO, id_thread_target);
186 if( handle_thread_target != (HANDLE)0 )
187 {
188 if( WaitForSingleObject(handle_thread_target, INFINITE) == WAIT_OBJECT_0 )
189 result = 0;
190
191 CloseHandle(handle_thread_target);
192 }
193
194 return result;
195}
196
197// Threadvars ----------------------------------------------------------------------------------------------------------
198
199POLAR_FUNCTION_INTERNAL intptr_t
200tss_create( tss_t *out_tss_id, tss_dtor_t __func_destructor_unused OBJC_IGNORE_UNUSED )
201{
202 tss_t tvar_id_new;
203
204 assert( out_tss_id != NULL );
205
206 tvar_id_new = TlsAlloc();
207 if( tvar_id_new != TLS_OUT_OF_INDEXES )
208 {
209 *out_tss_id = tvar_id_new;
210 return 0;
211 }
212
213 else
214 return -1;
215}
216
217// ---------------------------------------------------------------------------------------------------------------------
218
219// Called by polar_init()
220POLAR_FUNCTION_INTERNAL intptr_t
222{
223 // Nothing to do here
224 POLAR_DEBUG_FUNCTION_END;
225
226 return 0;
227}
228
229// Called by polar_finalize()
230POLAR_FUNCTION_INTERNAL void
232{
233 // Nothing to do here
234 POLAR_DEBUG_FUNCTION_END;
235}
236
void polar_platform_threading_finalize(void)
Definition polar-windows-platform-threading.c:231
static void mtx_destroy(mtx_t *p_mutex)
Definition polar-windows-platform-threading.h:49
DWORD thrd_t
Definition polar-windows-platform-threading.h:111
intptr_t cnd_signal(cnd_t *p_cond)
Definition polar-windows-platform-threading.c:102
PTHREAD_START_ROUTINE thrd_start_t
Definition polar-windows-platform-threading.h:113
intptr_t tss_create(tss_t *out_tss_id, tss_dtor_t __func_destructor_unused)
Definition polar-windows-platform-threading.c:200
CRITICAL_SECTION mtx_t
Definition polar-windows-platform-threading.h:31
intptr_t thrd_create(thrd_t *out_thread_id, thrd_start_t thread_func, void *thread_data)
Definition polar-windows-platform-threading.c:160
intptr_t cnd_init(cnd_t *p_cond)
Definition polar-windows-platform-threading.c:27
static intptr_t mtx_init(mtx_t *p_mutex, intptr_t tp_mutex)
Definition polar-windows-platform-threading.h:39
intptr_t cnd_broadcast(cnd_t *p_cond)
Definition polar-windows-platform-threading.c:67
static intptr_t mtx_lock(mtx_t *p_mutex)
Definition polar-windows-platform-threading.h:56
void * tss_dtor_t
Definition polar-windows-platform-threading.h:162
intptr_t thrd_join(thrd_t id_thread_target, intptr_t *__p_retval_unused)
Definition polar-windows-platform-threading.c:178
DWORD tss_t
Definition polar-windows-platform-threading.h:161
static intptr_t mtx_unlock(mtx_t *p_mutex)
Definition polar-windows-platform-threading.h:77
intptr_t cnd_wait(cnd_t *p_cond, mtx_t *p_mutex)
Definition polar-windows-platform-threading.c:133
void cnd_destroy(cnd_t *p_cond)
Definition polar-windows-platform-threading.c:40
intptr_t polar_platform_threading_init(void)
Definition polar-windows-platform-threading.c:221
@ mtx_recursive
Definition polar-windows-platform-threading.h:35
Definition polar-windows-platform-threading.h:88
DWORD TlsAlloc
DWORD WaitForSingleObject