Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit e79a687

Browse files
committed
make thread_term @nogc
- needed to replace destroy with manual destruction - use custom monitor deletion that does not call any event hooks
1 parent eef723d commit e79a687

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

src/core/thread.d

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,7 +1736,7 @@ private:
17361736
}
17371737
}
17381738

1739-
static void termLocks()
1739+
static void termLocks() @nogc
17401740
{
17411741
foreach (ref lock; _locks)
17421742
(cast(Mutex)lock.ptr).__dtor();
@@ -2090,20 +2090,28 @@ extern (C) void thread_init() @nogc
20902090
status = sem_init( &suspendCount, 0, 0 );
20912091
assert( status == 0 );
20922092
}
2093-
__gshared align(Thread.alignof) void[__traits(classInstanceSize, Thread)] mainThread;
20942093
if (typeid(Thread).initializer.ptr)
2095-
mainThread[] = typeid(Thread).initializer[];
2096-
Thread.sm_main = attachThread((cast(Thread)mainThread.ptr).__ctor());
2094+
_mainThreadStore[] = typeid(Thread).initializer[];
2095+
Thread.sm_main = attachThread((cast(Thread)_mainThreadStore.ptr).__ctor());
20972096
}
20982097

2098+
private __gshared align(Thread.alignof) void[__traits(classInstanceSize, Thread)] _mainThreadStore;
2099+
2100+
extern (C) void _d_monitordelete_nogc(Object h) @nogc;
20992101

21002102
/**
21012103
* Terminates the thread module. No other thread routine may be called
21022104
* afterwards.
21032105
*/
2104-
extern (C) void thread_term()
2106+
extern (C) void thread_term() @nogc
21052107
{
2106-
destroy(Thread.sm_main);
2108+
assert(_mainThreadStore.ptr is cast(void*) Thread.sm_main);
2109+
2110+
// destruct manually as object.destroy is not @nogc
2111+
Thread.sm_main.__dtor();
2112+
_d_monitordelete_nogc(Thread.sm_main);
2113+
if (typeid(Thread).initializer.ptr)
2114+
_mainThreadStore[] = typeid(Thread).initializer[];
21072115
Thread.sm_main = null;
21082116

21092117
assert(Thread.sm_tbeg && Thread.sm_tlen == 1);

src/rt/monitor_.d

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ extern (C) void _d_monitordelete(Object h, bool det)
5656
}
5757
}
5858

59+
// does not call dispose events, for internal use only
60+
extern (C) void _d_monitordelete_nogc(Object h) @nogc
61+
{
62+
auto m = getMonitor(h);
63+
if (m is null)
64+
return;
65+
66+
if (m.impl)
67+
{
68+
// let the GC collect the monitor
69+
setMonitor(h, null);
70+
}
71+
else if (!atomicOp!("-=")(m.refs, cast(size_t) 1))
72+
{
73+
// refcount == 0 means unshared => no synchronization required
74+
deleteMonitor(cast(Monitor*) m);
75+
setMonitor(h, null);
76+
}
77+
}
78+
5979
extern (C) void _d_monitorenter(Object h)
6080
in
6181
{
@@ -173,6 +193,7 @@ else version (Posix)
173193
{
174194
import core.sys.posix.pthread;
175195

196+
@nogc:
176197
alias Mutex = pthread_mutex_t;
177198
__gshared pthread_mutexattr_t gattr;
178199

@@ -211,17 +232,17 @@ struct Monitor
211232

212233
private:
213234

214-
@property ref shared(Monitor*) monitor(Object h) pure nothrow
235+
@property ref shared(Monitor*) monitor(Object h) pure nothrow @nogc
215236
{
216237
return *cast(shared Monitor**)&h.__monitor;
217238
}
218239

219-
private shared(Monitor)* getMonitor(Object h) pure
240+
private shared(Monitor)* getMonitor(Object h) pure @nogc
220241
{
221242
return atomicLoad!(MemoryOrder.acq)(h.monitor);
222243
}
223244

224-
void setMonitor(Object h, shared(Monitor)* m) pure
245+
void setMonitor(Object h, shared(Monitor)* m) pure @nogc
225246
{
226247
atomicStore!(MemoryOrder.rel)(h.monitor, m);
227248
}
@@ -263,7 +284,7 @@ shared(Monitor)* ensureMonitor(Object h)
263284
}
264285
}
265286

266-
void deleteMonitor(Monitor* m)
287+
void deleteMonitor(Monitor* m) @nogc
267288
{
268289
destroyMutex(&m.mtx);
269290
free(m);

0 commit comments

Comments
 (0)