annotate src/core/threads.c @ 40:9b496a0c430a

merge
author anatofuz
date Tue, 27 Nov 2018 11:25:43 +0900
parents 2cf249471370
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 #include "moar.h"
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 #include <platform/threads.h>
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 /* Temporary structure for passing data to thread start. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 typedef struct {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 MVMThreadContext *tc;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 MVMObject *thread_obj;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 } ThreadStart;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 /* Creates a new thread handle with the MVMThread representation. Does not
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 * actually start execution of the thread, but does give it its unique ID. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 MVMObject * MVM_thread_new(MVMThreadContext *tc, MVMObject *invokee, MVMint64 app_lifetime) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 MVMThread *thread;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 MVMThreadContext *child_tc;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 unsigned int interval_id;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 interval_id = MVM_telemetry_interval_start(tc, "spawning a new thread off of me");
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 /* Create the Thread object and stash code to run and lifetime. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 MVMROOT(tc, invokee, {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 thread = (MVMThread *)MVM_repr_alloc_init(tc, tc->instance->Thread);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 });
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 thread->body.stage = MVM_thread_stage_unstarted;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 MVM_ASSIGN_REF(tc, &(thread->common.header), thread->body.invokee, invokee);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 thread->body.app_lifetime = app_lifetime;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 /* Try to create the new threadcontext. Can throw if libuv can't
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 * create a loop for it for some reason (i.e. too many open files) */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 MVMROOT(tc, thread, {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 child_tc = MVM_tc_create(tc, tc->instance);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 });
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 /* Set up the new threadcontext a little. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 child_tc->thread_obj = thread;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 child_tc->thread_id = 1 + MVM_incr(&tc->instance->next_user_thread_id);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 /* Add one, since MVM_incr returns original. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 thread->body.tc = child_tc;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 MVM_telemetry_interval_stop(child_tc, interval_id, "i'm the newly spawned thread.");
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 /* Also make a copy of the thread ID in the thread object itself, so it
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 * is available once the thread dies and its ThreadContext is gone. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 thread->body.thread_id = child_tc->thread_id;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 return (MVMObject *)thread;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 /* This callback is passed to the interpreter code. It takes care of making
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 * the initial invocation of the thread code. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 static void thread_initial_invoke(MVMThreadContext *tc, void *data) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 /* The passed data is simply the code object to invoke. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 ThreadStart *ts = (ThreadStart *)data;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 MVMThread *thread = (MVMThread *)ts->thread_obj;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 MVMObject *invokee = thread->body.invokee;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 thread->body.invokee = NULL;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 /* Create initial frame, which sets up all of the interpreter state also. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 invokee = MVM_frame_find_invokee(tc, invokee, NULL);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 STABLE(invokee)->invoke(tc, invokee, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS), NULL);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 /* This frame should be marked as the thread entry frame, so that any
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 * return from it will cause us to drop out of the interpreter and end
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 * the thread. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 tc->thread_entry_frame = tc->cur_frame;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 /* This callback handles starting execution of a thread. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 static void start_thread(void *data) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 ThreadStart *ts = (ThreadStart *)data;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 MVMThreadContext *tc = ts->tc;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 /* wait for the GC to finish if it's not finished stealing us. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 MVM_gc_mark_thread_unblocked(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 tc->thread_obj->body.stage = MVM_thread_stage_started;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 /* Stash thread ID. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 tc->thread_obj->body.native_thread_id = MVM_platform_thread_id();
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 /* Create a spesh log for this thread, unless it's just going to run C
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 * code (and thus it's a VM internal worker). */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 if (REPR(tc->thread_obj->body.invokee)->ID != MVM_REPR_ID_MVMCFunction)
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 MVM_spesh_log_initialize_thread(tc, 0);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 MVM_debugserver_notify_thread_creation(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 /* Enter the interpreter, to run code. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 MVM_interp_run(tc, thread_initial_invoke, ts);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 MVM_debugserver_notify_thread_destruction(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 /* Pop the temp root stack's ts->thread_obj, if it's still there (if we
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 * cleared the temp root stack on exception at some point, it'll already be
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 * gone). */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 if (tc->num_temproots != 0)
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 MVM_gc_root_temp_pop_n(tc, tc->num_temproots);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 MVM_free(ts);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 /* Mark as exited, so the GC will know to clear our stuff. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 tc->thread_obj->body.stage = MVM_thread_stage_exited;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 /* Mark ourselves as blocked, so that another thread will take care
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 * of GC-ing our objects and cleaning up our thread context. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 MVM_gc_mark_thread_blocked(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 /* Exit the thread, now it's completed. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 MVM_platform_thread_exit(NULL);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 /* Begins execution of a thread. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 void MVM_thread_run(MVMThreadContext *tc, MVMObject *thread_obj) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 MVMThread *child = (MVMThread *)thread_obj;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 int status, added;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 ThreadStart *ts;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 if (REPR(child)->ID == MVM_REPR_ID_MVMThread && IS_CONCRETE(thread_obj)) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 MVMThreadContext *child_tc = child->body.tc;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 /* Mark thread as GC blocked until the thread actually starts. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 MVM_gc_mark_thread_blocked(child_tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 /* Create thread state, to pass to the thread start callback. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 ts = MVM_malloc(sizeof(ThreadStart));
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 ts->tc = child_tc;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 /* Push to starting threads list. We may need to retry this if we are
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 * asked to join a GC run at this point (since the GC would already
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 * have taken a snapshot of the thread list, so it's not safe to add
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 * another at this point). */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 added = 0;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 while (!added) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 uv_mutex_lock(&tc->instance->mutex_threads);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 if (MVM_load(&tc->gc_status) == MVMGCStatus_NONE) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 /* Insert into list. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 MVM_ASSIGN_REF(tc, &(child->common.header), child->body.next,
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 tc->instance->threads);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 tc->instance->threads = child;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 /* Store the thread object in the thread start information and
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 * keep it alive by putting it in the *child* tc's temp roots. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 ts->thread_obj = thread_obj;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 MVM_gc_root_temp_push(child_tc, (MVMCollectable **)&ts->thread_obj);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 /* Move thread to starting stage. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 child->body.stage = MVM_thread_stage_starting;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 /* Mark us done and unlock the mutex; any GC run will now have
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 * a consistent view of the thread list and can safely run. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 added = 1;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 uv_mutex_unlock(&tc->instance->mutex_threads);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 else {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 /* Another thread decided we'll GC now. Release mutex, and
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 * do the GC, making sure thread_obj and child are marked. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 uv_mutex_unlock(&tc->instance->mutex_threads);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 MVMROOT2(tc, thread_obj, child, {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 GC_SYNC_POINT(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 });
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 /* Do the actual thread creation. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 status = uv_thread_create(&child->body.thread, start_thread, ts);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 if (status < 0)
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 MVM_panic(MVM_exitcode_compunit, "Could not spawn thread: errorcode %d", status);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 else {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 MVM_exception_throw_adhoc(tc,
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 "Thread handle passed to run must have representation MVMThread");
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 /* Waits for a thread to finish. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 static int try_join(MVMThreadContext *tc, MVMThread *thread) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 /* Join the thread, marking ourselves as unable to GC while we wait. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 int status;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 MVM_gc_root_temp_push(tc, (MVMCollectable **)&thread);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 MVM_gc_mark_thread_blocked(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 if (thread->body.stage < MVM_thread_stage_exited) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 status = uv_thread_join(&thread->body.thread);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 else {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 /* the target already ended */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 status = 0;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 MVM_gc_mark_thread_unblocked(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 MVM_gc_root_temp_pop(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 /* After a thread has been joined, we trigger a GC run to clean up after
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 * it. This avoids problems where a program spawns threads and joins them
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 * in a loop gobbling a load of memory and other resources because we do
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 * not ever trigger a GC run to clean up the thread. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 MVM_gc_enter_from_allocator(tc);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 return status;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 void MVM_thread_join(MVMThreadContext *tc, MVMObject *thread_obj) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 if (REPR(thread_obj)->ID == MVM_REPR_ID_MVMThread && IS_CONCRETE(thread_obj)) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 int status = try_join(tc, (MVMThread *)thread_obj);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 if (status < 0)
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 MVM_panic(MVM_exitcode_compunit, "Could not join thread: errorcode %d", status);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 else {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 MVM_exception_throw_adhoc(tc,
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 "Thread handle passed to join must have representation MVMThread");
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 /* Gets the (VM-level) ID of a thread. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 MVMint64 MVM_thread_id(MVMThreadContext *tc, MVMObject *thread_obj) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 if (REPR(thread_obj)->ID == MVM_REPR_ID_MVMThread && IS_CONCRETE(thread_obj))
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 return ((MVMThread *)thread_obj)->body.thread_id;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 else
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 MVM_exception_throw_adhoc(tc,
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 "Thread handle passed to threadid must have representation MVMThread");
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 /* Gets the native OS ID of a thread. If it's not yet available because
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 * the thread was not yet started, this will return 0. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 MVMint64 MVM_thread_native_id(MVMThreadContext *tc, MVMObject *thread_obj) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 if (REPR(thread_obj)->ID == MVM_REPR_ID_MVMThread && IS_CONCRETE(thread_obj))
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 return ((MVMThread *)thread_obj)->body.native_thread_id;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 else
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 MVM_exception_throw_adhoc(tc,
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 "Thread handle passed to threadnativeid must have representation MVMThread");
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 /* Yields control to another thread. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 void MVM_thread_yield(MVMThreadContext *tc) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 MVM_telemetry_timestamp(tc, "thread yielding");
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 MVM_platform_thread_yield();
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 /* Gets the object representing the current thread. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 MVMObject * MVM_thread_current(MVMThreadContext *tc) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 return (MVMObject *)tc->thread_obj;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 /* Gets the number of locks held by a thread. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 MVMint64 MVM_thread_lock_count(MVMThreadContext *tc, MVMObject *thread_obj) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 if (REPR(thread_obj)->ID == MVM_REPR_ID_MVMThread && IS_CONCRETE(thread_obj)) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 MVMThreadContext *thread_tc = ((MVMThread *)thread_obj)->body.tc;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 return thread_tc ? thread_tc->num_locks : 0;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 else {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 MVM_exception_throw_adhoc(tc,
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 "Thread handle used with threadlockcount must have representation MVMThread");
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 void MVM_thread_cleanup_threads_list(MVMThreadContext *tc, MVMThread **head) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 /* Assumed to be the only thread accessing the list.
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 * must set next on every item. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 MVMThread *new_list = NULL, *this = *head, *next;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 *head = NULL;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 while (this) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 next = this->body.next;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 switch (this->body.stage) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 case MVM_thread_stage_starting:
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 case MVM_thread_stage_waiting:
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 case MVM_thread_stage_started:
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 case MVM_thread_stage_exited:
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 case MVM_thread_stage_clearing_nursery:
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 /* push it to the new starting list */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 this->body.next = new_list;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 new_list = this;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 break;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 case MVM_thread_stage_destroyed:
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 /* don't put in a list */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 this->body.next = NULL;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 break;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 default:
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 MVM_panic(MVM_exitcode_threads, "Thread in unknown stage: %"MVM_PRSz"\n", this->body.stage);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 this = next;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 *head = new_list;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 /* Goes through all non-app-lifetime threads and joins them. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 void MVM_thread_join_foreground(MVMThreadContext *tc) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 MVMint64 work = 1;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 while (work) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 MVMThread *cur_thread = tc->instance->threads;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 work = 0;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 while (cur_thread) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 if (cur_thread->body.tc != tc->instance->main_thread) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 if (!cur_thread->body.app_lifetime) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 if (MVM_load(&cur_thread->body.stage) < MVM_thread_stage_exited) {
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 /* Join may trigger GC and invalidate cur_thread, so we
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 * just set work to 1 and do another trip around the main
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 * loop. */
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 try_join(tc, cur_thread);
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 work = 1;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 break;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 cur_thread = cur_thread->body.next;
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 }
2cf249471370 convert mercurial for git
Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302