Skip to content

Commit 01add0d

Browse files
author
埃博拉酱
committed
mutex
1 parent 4d6afde commit 01add0d

File tree

6 files changed

+1177
-49
lines changed

6 files changed

+1177
-49
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"concepts": "cpp",
101101
"numbers": "cpp",
102102
"format": "cpp",
103-
"variant": "cpp"
103+
"variant": "cpp",
104+
"mutex": "cpp"
104105
}
105106
}

examples/Mutex/Mutex.ino

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <Cpp_Standard_Library.h>
2+
#include <mutex>
3+
void setup() {
4+
Serial.begin(9600);
5+
std::mutex Mutex;
6+
std::lock_guard LockGuard{ Mutex };
7+
8+
Serial.println("已锁定");
9+
10+
Serial.flush();
11+
/*
12+
此调用永远不会返回,也永远不会输出上面写的文字,因为上了锁之后无法中断,串口缓存依赖中断输出,无法中断就永远无法输出,卡死在这里。
13+
反之,如果注释掉这一行,反而能输出文字,因为此函数结束后会解锁,串口缓存得以输出。
14+
*/
15+
}
16+
void loop() {}

src/bits/gthr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include<bits/gthr.h>
2+
std::unordered_set<__gthread_mutex_t*> _CSL_MutexSet;

src/bits/gthr.h

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#pragma once
2-
#ifdef ARDUINO_ARCH_AVR
2+
// 此文件为架构特定,由埃博拉酱手动实现
33
/* Threads compatibility routines for libgcc2 and libobjc. */
44
/* Compile this one with gcc. */
55
/* Copyright (C) 1997-2024 Free Software Foundation, Inc.
@@ -28,6 +28,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2828
#ifndef GCC_GTHR_SINGLE_H
2929
#define GCC_GTHR_SINGLE_H
3030

31+
#include <unordered_set>
32+
#include <cerrno>
33+
#include <Arduino.h>
34+
3135
/* Just provide compatibility for mutex handling. */
3236

3337
typedef int __gthread_key_t;
@@ -37,7 +41,10 @@ typedef int __gthread_recursive_mutex_t;
3741

3842
#define __GTHREAD_ONCE_INIT 0
3943
#define __GTHREAD_MUTEX_INIT 0
40-
#define __GTHREAD_MUTEX_INIT_FUNCTION(mx) do {} while (0)
44+
#define __GTHREAD_MUTEX_INIT_FUNCTION(mx) \
45+
do \
46+
{ \
47+
} while (0)
4148
#define __GTHREAD_RECURSIVE_MUTEX_INIT 0
4249

4350
#define UNUSED __attribute__((__unused__))
@@ -51,15 +58,15 @@ static void *thread_local_storage = NULL;
5158

5259
/* Initialize the threads subsystem. */
5360
static inline int
54-
__gthread_objc_init_thread_system (void)
61+
__gthread_objc_init_thread_system(void)
5562
{
5663
/* No thread support available */
5764
return -1;
5865
}
5966

6067
/* Close the threads subsystem. */
6168
static inline int
62-
__gthread_objc_close_thread_system (void)
69+
__gthread_objc_close_thread_system(void)
6370
{
6471
/* No thread support available */
6572
return -1;
@@ -69,37 +76,37 @@ __gthread_objc_close_thread_system (void)
6976

7077
/* Create a new thread of execution. */
7178
static inline objc_thread_t
72-
__gthread_objc_thread_detach (void (* func)(void *), void * arg UNUSED)
79+
__gthread_objc_thread_detach(void (*func)(void *), void *arg UNUSED)
7380
{
7481
/* No thread support available */
7582
return NULL;
7683
}
7784

7885
/* Set the current thread's priority. */
7986
static inline int
80-
__gthread_objc_thread_set_priority (int priority UNUSED)
87+
__gthread_objc_thread_set_priority(int priority UNUSED)
8188
{
8289
/* No thread support available */
8390
return -1;
8491
}
8592

8693
/* Return the current thread's priority. */
8794
static inline int
88-
__gthread_objc_thread_get_priority (void)
95+
__gthread_objc_thread_get_priority(void)
8996
{
9097
return OBJC_THREAD_INTERACTIVE_PRIORITY;
9198
}
9299

93100
/* Yield our process time to another thread. */
94101
static inline void
95-
__gthread_objc_thread_yield (void)
102+
__gthread_objc_thread_yield(void)
96103
{
97104
return;
98105
}
99106

100107
/* Terminate the current thread. */
101108
static inline int
102-
__gthread_objc_thread_exit (void)
109+
__gthread_objc_thread_exit(void)
103110
{
104111
/* No thread support available */
105112
/* Should we really exit the program */
@@ -109,23 +116,23 @@ __gthread_objc_thread_exit (void)
109116

110117
/* Returns an integer value which uniquely describes a thread. */
111118
static inline objc_thread_t
112-
__gthread_objc_thread_id (void)
119+
__gthread_objc_thread_id(void)
113120
{
114121
/* No thread support, use 1. */
115-
return (objc_thread_t) 1;
122+
return (objc_thread_t)1;
116123
}
117124

118125
/* Sets the thread's local storage pointer. */
119126
static inline int
120-
__gthread_objc_thread_set_data (void *value)
127+
__gthread_objc_thread_set_data(void *value)
121128
{
122129
thread_local_storage = value;
123130
return 0;
124131
}
125132

126133
/* Returns the thread's local storage pointer. */
127134
static inline void *
128-
__gthread_objc_thread_get_data (void)
135+
__gthread_objc_thread_get_data(void)
129136
{
130137
return thread_local_storage;
131138
}
@@ -134,37 +141,37 @@ __gthread_objc_thread_get_data (void)
134141

135142
/* Allocate a mutex. */
136143
static inline int
137-
__gthread_objc_mutex_allocate (objc_mutex_t mutex UNUSED)
144+
__gthread_objc_mutex_allocate(objc_mutex_t mutex UNUSED)
138145
{
139146
return 0;
140147
}
141148

142149
/* Deallocate a mutex. */
143150
static inline int
144-
__gthread_objc_mutex_deallocate (objc_mutex_t mutex UNUSED)
151+
__gthread_objc_mutex_deallocate(objc_mutex_t mutex UNUSED)
145152
{
146153
return 0;
147154
}
148155

149156
/* Grab a lock on a mutex. */
150157
static inline int
151-
__gthread_objc_mutex_lock (objc_mutex_t mutex UNUSED)
158+
__gthread_objc_mutex_lock(objc_mutex_t mutex UNUSED)
152159
{
153160
/* There can only be one thread, so we always get the lock */
154161
return 0;
155162
}
156163

157164
/* Try to grab a lock on a mutex. */
158165
static inline int
159-
__gthread_objc_mutex_trylock (objc_mutex_t mutex UNUSED)
166+
__gthread_objc_mutex_trylock(objc_mutex_t mutex UNUSED)
160167
{
161168
/* There can only be one thread, so we always get the lock */
162169
return 0;
163170
}
164171

165172
/* Unlock the mutex */
166173
static inline int
167-
__gthread_objc_mutex_unlock (objc_mutex_t mutex UNUSED)
174+
__gthread_objc_mutex_unlock(objc_mutex_t mutex UNUSED)
168175
{
169176
return 0;
170177
}
@@ -173,131 +180,136 @@ __gthread_objc_mutex_unlock (objc_mutex_t mutex UNUSED)
173180

174181
/* Allocate a condition. */
175182
static inline int
176-
__gthread_objc_condition_allocate (objc_condition_t condition UNUSED)
183+
__gthread_objc_condition_allocate(objc_condition_t condition UNUSED)
177184
{
178185
return 0;
179186
}
180187

181188
/* Deallocate a condition. */
182189
static inline int
183-
__gthread_objc_condition_deallocate (objc_condition_t condition UNUSED)
190+
__gthread_objc_condition_deallocate(objc_condition_t condition UNUSED)
184191
{
185192
return 0;
186193
}
187194

188195
/* Wait on the condition */
189196
static inline int
190-
__gthread_objc_condition_wait (objc_condition_t condition UNUSED,
191-
objc_mutex_t mutex UNUSED)
197+
__gthread_objc_condition_wait(objc_condition_t condition UNUSED,
198+
objc_mutex_t mutex UNUSED)
192199
{
193200
return 0;
194201
}
195202

196203
/* Wake up all threads waiting on this condition. */
197204
static inline int
198-
__gthread_objc_condition_broadcast (objc_condition_t condition UNUSED)
205+
__gthread_objc_condition_broadcast(objc_condition_t condition UNUSED)
199206
{
200207
return 0;
201208
}
202209

203210
/* Wake up one thread waiting on this condition. */
204211
static inline int
205-
__gthread_objc_condition_signal (objc_condition_t condition UNUSED)
212+
__gthread_objc_condition_signal(objc_condition_t condition UNUSED)
206213
{
207214
return 0;
208215
}
209216

210217
#else /* _LIBOBJC */
211218

212219
static inline int
213-
__gthread_active_p (void)
220+
__gthread_active_p(void)
214221
{
215222
return 0;
216223
}
217224

218225
static inline int
219-
__gthread_once (__gthread_once_t *__once UNUSED, void (*__func) (void) UNUSED)
226+
__gthread_once(__gthread_once_t *__once UNUSED, void (*__func)(void) UNUSED)
220227
{
221228
return 0;
222229
}
223230

224231
static inline int UNUSED
225-
__gthread_key_create (__gthread_key_t *__key UNUSED, void (*__func) (void *) UNUSED)
232+
__gthread_key_create(__gthread_key_t *__key UNUSED, void (*__func)(void *) UNUSED)
226233
{
227234
return 0;
228235
}
229236

230237
static int UNUSED
231-
__gthread_key_delete (__gthread_key_t __key UNUSED)
238+
__gthread_key_delete(__gthread_key_t __key UNUSED)
232239
{
233240
return 0;
234241
}
235242

236243
static inline void *
237-
__gthread_getspecific (__gthread_key_t __key UNUSED)
244+
__gthread_getspecific(__gthread_key_t __key UNUSED)
238245
{
239246
return 0;
240247
}
241248

242249
static inline int
243-
__gthread_setspecific (__gthread_key_t __key UNUSED, const void *__v UNUSED)
250+
__gthread_setspecific(__gthread_key_t __key UNUSED, const void *__v UNUSED)
244251
{
245252
return 0;
246253
}
247254

248255
static inline int
249-
__gthread_mutex_destroy (__gthread_mutex_t *__mutex UNUSED)
256+
__gthread_mutex_destroy(__gthread_mutex_t *__mutex UNUSED)
250257
{
251258
return 0;
252259
}
253-
260+
extern std::unordered_set<__gthread_mutex_t *> _CSL_MutexSet;
254261
static inline int
255-
__gthread_mutex_lock (__gthread_mutex_t *__mutex UNUSED)
262+
__gthread_mutex_lock(__gthread_mutex_t *__mutex)
256263
{
257-
return 0;
264+
if (_CSL_MutexSet.contains(__mutex))
265+
return EBUSY;
266+
else
267+
{
268+
if (_CSL_MutexSet.empty())
269+
noInterrupts();
270+
_CSL_MutexSet.insert(__mutex);
271+
return 0;
272+
}
258273
}
259274

260275
static inline int
261-
__gthread_mutex_trylock (__gthread_mutex_t *__mutex UNUSED)
276+
__gthread_mutex_trylock(__gthread_mutex_t *__mutex UNUSED)
262277
{
263278
return 0;
264279
}
265280

266281
static inline int
267-
__gthread_mutex_unlock (__gthread_mutex_t *__mutex UNUSED)
282+
__gthread_mutex_unlock(__gthread_mutex_t *__mutex UNUSED)
268283
{
269284
return 0;
270285
}
271286

272287
static inline int
273-
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
288+
__gthread_recursive_mutex_lock(__gthread_recursive_mutex_t *__mutex)
274289
{
275-
return __gthread_mutex_lock (__mutex);
290+
return __gthread_mutex_lock(__mutex);
276291
}
277292

278293
static inline int
279-
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
294+
__gthread_recursive_mutex_trylock(__gthread_recursive_mutex_t *__mutex)
280295
{
281-
return __gthread_mutex_trylock (__mutex);
296+
return __gthread_mutex_trylock(__mutex);
282297
}
283298

284299
static inline int
285-
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
300+
__gthread_recursive_mutex_unlock(__gthread_recursive_mutex_t *__mutex)
286301
{
287-
return __gthread_mutex_unlock (__mutex);
302+
return __gthread_mutex_unlock(__mutex);
288303
}
289304

290305
static inline int
291-
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
306+
__gthread_recursive_mutex_destroy(__gthread_recursive_mutex_t *__mutex)
292307
{
293-
return __gthread_mutex_destroy (__mutex);
308+
return __gthread_mutex_destroy(__mutex);
294309
}
295310

296311
#endif /* _LIBOBJC */
297312

298313
#undef UNUSED
299314

300-
#endif /* ! GCC_GTHR_SINGLE_H */
301-
#else
302-
#include_next <bits/gthr.h>
303-
#endif
315+
#endif /* ! GCC_GTHR_SINGLE_H */

0 commit comments

Comments
 (0)