Skip to content

Commit ffb43b2

Browse files
dlechdpgeorge
authored andcommitted
py/modthread: Return thread id from start_new_thread().
In CPython, `_thread.start_new_thread()` returns an ID that is the same ID that is returned by `_thread.get_ident()`. The current MicroPython implementation of `_thread.start_new_thread()` always returns `None`. This modifies the required functions to return a value. The native thread id is returned since this can be used for interop with other functions, for example, `pthread_kill()` on *nix. `_thread.get_ident()` is also modified to return the native thread id so that the values match and avoids the need for a separate `native_id` attribute. Fixes issue micropython#12153. Signed-off-by: David Lechner <[email protected]>
1 parent c0d4c60 commit ffb43b2

File tree

9 files changed

+58
-16
lines changed

9 files changed

+58
-16
lines changed

ports/cc3200/mpthreadport.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ void mp_thread_set_state(mp_state_thread_t *state) {
8989
vTaskSetThreadLocalStoragePointer(NULL, 0, state);
9090
}
9191

92+
mp_uint_t mp_thread_get_id(void) {
93+
return (mp_uint_t)xTaskGetCurrentTaskHandle();
94+
}
95+
9296
void mp_thread_start(void) {
9397
mp_thread_mutex_lock(&thread_mutex, 1);
9498
for (mp_thread_t *th = thread; th != NULL; th = th->next) {
@@ -111,7 +115,7 @@ STATIC void freertos_entry(void *arg) {
111115
}
112116
}
113117

114-
void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
118+
mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
115119
// store thread entry function into a global variable so we can access it
116120
ext_thread_entry = entry;
117121

@@ -148,6 +152,9 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
148152

149153
// adjust stack_size to provide room to recover from hitting the limit
150154
*stack_size -= 512;
155+
156+
MP_STATIC_ASSERT(sizeof(mp_uint_t) >= sizeof(TaskHandle_t));
157+
return (mp_uint_t)id;
151158
}
152159

153160
void mp_thread_finish(void) {

ports/esp32/mpthreadport.c

+9-3
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ void mp_thread_set_state(mp_state_thread_t *state) {
9898
vTaskSetThreadLocalStoragePointer(NULL, 1, state);
9999
}
100100

101+
mp_uint_t mp_thread_get_id(void) {
102+
return (mp_uint_t)xTaskGetCurrentTaskHandle();
103+
}
104+
101105
void mp_thread_start(void) {
102106
mp_thread_mutex_lock(&thread_mutex, 1);
103107
for (mp_thread_t *th = thread; th != NULL; th = th->next) {
@@ -120,7 +124,7 @@ STATIC void freertos_entry(void *arg) {
120124
}
121125
}
122126

123-
void mp_thread_create_ex(void *(*entry)(void *), void *arg, size_t *stack_size, int priority, char *name) {
127+
mp_uint_t mp_thread_create_ex(void *(*entry)(void *), void *arg, size_t *stack_size, int priority, char *name) {
124128
// store thread entry function into a global variable so we can access it
125129
ext_thread_entry = entry;
126130

@@ -154,10 +158,12 @@ void mp_thread_create_ex(void *(*entry)(void *), void *arg, size_t *stack_size,
154158
*stack_size -= 1024;
155159

156160
mp_thread_mutex_unlock(&thread_mutex);
161+
162+
return (mp_uint_t)th->id;
157163
}
158164

159-
void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
160-
mp_thread_create_ex(entry, arg, stack_size, MP_THREAD_PRIORITY, "mp_thread");
165+
mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
166+
return mp_thread_create_ex(entry, arg, stack_size, MP_THREAD_PRIORITY, "mp_thread");
161167
}
162168

163169
void mp_thread_finish(void) {

ports/renesas-ra/mpthreadport.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ void mp_thread_gc_others(void) {
5454
mp_thread_mutex_unlock(&thread_mutex);
5555
}
5656

57-
void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
57+
mp_uint_t mp_thread_get_id(void) {
58+
return (uint32_t)pyb_thread_cur;
59+
}
60+
61+
mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
5862
if (*stack_size == 0) {
5963
*stack_size = 4096; // default stack size
6064
} else if (*stack_size < 2048) {
@@ -82,6 +86,8 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
8286

8387
// adjust stack_size to provide room to recover from hitting the limit
8488
*stack_size -= 1024;
89+
90+
return id;
8591
}
8692

8793
void mp_thread_start(void) {

ports/rp2/mpthreadport.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,13 @@ STATIC void core1_entry_wrapper(void) {
116116
// returning from here will loop the core forever (WFI)
117117
}
118118

119-
void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
119+
mp_uint_t mp_thread_get_id(void) {
120+
// On RP2, there are only two threads, one for each core, so the thread id
121+
// is the core number.
122+
return get_core_num();
123+
}
124+
125+
mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
120126
// Check if core1 is already in use.
121127
if (core1_entry != NULL) {
122128
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("core1 in use"));
@@ -144,6 +150,8 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
144150

145151
// Adjust stack_size to provide room to recover from hitting the limit.
146152
*stack_size -= 512;
153+
154+
return 1;
147155
}
148156

149157
void mp_thread_start(void) {

ports/stm32/mpthreadport.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ void mp_thread_gc_others(void) {
5454
mp_thread_mutex_unlock(&thread_mutex);
5555
}
5656

57-
void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
57+
mp_uint_t mp_thread_get_id(void) {
58+
return (uint32_t)pyb_thread_cur;
59+
}
60+
61+
mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
5862
if (*stack_size == 0) {
5963
*stack_size = 4096; // default stack size
6064
} else if (*stack_size < 2048) {
@@ -82,6 +86,8 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
8286

8387
// adjust stack_size to provide room to recover from hitting the limit
8488
*stack_size -= 1024;
89+
90+
return id;
8591
}
8692

8793
void mp_thread_start(void) {

ports/unix/mpthreadport.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ void mp_thread_set_state(mp_state_thread_t *state) {
191191
pthread_setspecific(tls_key, state);
192192
}
193193

194+
mp_uint_t mp_thread_get_id(void) {
195+
return (mp_uint_t)pthread_self();
196+
}
197+
194198
void mp_thread_start(void) {
195199
// enable realtime priority if `-X realtime` command line parameter was set
196200
#if defined(__APPLE__)
@@ -210,7 +214,7 @@ void mp_thread_start(void) {
210214
mp_thread_unix_end_atomic_section();
211215
}
212216

213-
void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
217+
mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
214218
// default stack size is 8k machine-words
215219
if (*stack_size == 0) {
216220
*stack_size = 8192 * sizeof(void *);
@@ -265,7 +269,8 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
265269

266270
mp_thread_unix_end_atomic_section();
267271

268-
return;
272+
MP_STATIC_ASSERT(sizeof(mp_uint_t) >= sizeof(pthread_t));
273+
return (mp_uint_t)id;
269274

270275
er:
271276
mp_raise_OSError(ret);

py/modthread.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
129129
STATIC size_t thread_stack_size = 0;
130130

131131
STATIC mp_obj_t mod_thread_get_ident(void) {
132-
return mp_obj_new_int_from_uint((uintptr_t)mp_thread_get_state());
132+
return mp_obj_new_int_from_uint(mp_thread_get_id());
133133
}
134134
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_thread_get_ident_obj, mod_thread_get_ident);
135135

@@ -268,9 +268,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args)
268268
th_args->fun = args[0];
269269

270270
// spawn the thread!
271-
mp_thread_create(thread_entry, th_args, &th_args->stack_size);
272-
273-
return mp_const_none;
271+
return mp_obj_new_int_from_uint(mp_thread_create(thread_entry, th_args, &th_args->stack_size));
274272
}
275273
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_thread_start_new_thread_obj, 2, 3, mod_thread_start_new_thread);
276274

py/mpthread.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ struct _mp_state_thread_t;
4040

4141
struct _mp_state_thread_t *mp_thread_get_state(void);
4242
void mp_thread_set_state(struct _mp_state_thread_t *state);
43-
void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size);
43+
mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size);
44+
mp_uint_t mp_thread_get_id(void);
4445
void mp_thread_start(void);
4546
void mp_thread_finish(void);
4647
void mp_thread_mutex_init(mp_thread_mutex_t *mutex);

tests/thread/thread_ident1.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
import _thread
66

77

8+
tid = None
9+
10+
811
def thread_entry():
12+
global tid
913
tid = _thread.get_ident()
1014
print("thread", type(tid) == int, tid != 0, tid != tid_main)
1115
global finished
@@ -16,8 +20,9 @@ def thread_entry():
1620
print("main", type(tid_main) == int, tid_main != 0)
1721

1822
finished = False
19-
_thread.start_new_thread(thread_entry, ())
23+
new_tid = _thread.start_new_thread(thread_entry, ())
2024

2125
while not finished:
2226
pass
23-
print("done")
27+
28+
print("done", type(new_tid) == int, new_tid == tid)

0 commit comments

Comments
 (0)