Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/core/thread.d
Original file line number Diff line number Diff line change
Expand Up @@ -1393,13 +1393,12 @@ private:
lock[] = Mutex.classinfo.init[];
(cast(Mutex)lock.ptr).__ctor();
}
}

extern(C) void destroy()
{
foreach (ref lock; _locks)
(cast(Mutex)lock.ptr).__dtor();
}
atexit(&destroy);
static void termLocks()
{
foreach (ref lock; _locks)
(cast(Mutex)lock.ptr).__dtor();
}

__gshared Context* sm_cbeg;
Expand Down Expand Up @@ -1725,6 +1724,11 @@ extern (C) void thread_init()
Thread.sm_main = thread_attachThis();
}

extern (C) void thread_term()
{
Thread.termLocks();
}


/**
*
Expand Down
2 changes: 2 additions & 0 deletions src/gc/proxy.d
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ private
__gshared gc_t _gc;

extern (C) void thread_init();
extern (C) void thread_term();

struct Proxy
{
Expand Down Expand Up @@ -138,6 +139,7 @@ extern (C)
// static data area, roots, and ranges.
_gc.Dtor();

thread_term();
free(cast(void*)_gc);
_gc = null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/rt/deh_win64_posix.d
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ immutable(FuncTable)* __eh_finddata(void *address)
return null;
}

immutable(FuncTable)* __eh_finddata(void *address, immutable(FuncTable)* pstart, immutable(FuncTable)* pend)
nothrow immutable(FuncTable)* __eh_finddata(void *address, immutable(FuncTable)* pstart, immutable(FuncTable)* pend)
{
debug(PRINTF) printf("FuncTable.sizeof = %p\n", FuncTable.sizeof);
debug(PRINTF) printf("__eh_finddata(address = %p)\n", address);
Expand Down
73 changes: 48 additions & 25 deletions src/rt/dmain2.d
Original file line number Diff line number Diff line change
Expand Up @@ -243,21 +243,19 @@ extern (C) bool rt_init(ExceptionHandler dg = null)
initStaticDataGC();
rt_moduleCtor();
rt_moduleTlsCtor();
runModuleUnitTests();
return true;
}
catch (Throwable e)
{
/* Note that if we get here, the runtime is in an unknown state.
* I'm not sure what the point of calling dg is.
*/
if (dg)
dg(e);
else
if (!dg)
throw e; // rethrow, don't silently ignore error
/* Rethrow, and the two STD functions aren't called?
* This needs rethinking.
*/
/* Rethrow, and the two STD functions aren't called?
* This needs rethinking.
*/
dg(e);
}
_STD_critical_term();
_STD_monitor_staticdtor();
Expand All @@ -284,8 +282,9 @@ extern (C) bool rt_term(ExceptionHandler dg = null)
}
catch (Throwable e)
{
if (dg)
dg(e);
if (!dg)
throw e; // rethrow, don't silently ignore error

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with me, but should be separate commit.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine even though rt_init() is being called from C code?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that I adjusted the behavior of rt_term() to match that of rt_init() in regards to exceptions.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, when this propagates to all platforms, rt_init() will no longer be called by C code. The initialization will happen automatically, just by loading the DLL using the operating system call to do so.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd write this as

if (!dg) 
    throw e;
dg();

i.e. minimize flow control.

dg(e);
}
finally
{
Expand Down Expand Up @@ -375,9 +374,6 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
}
}

_STI_monitor_staticctor();
_STI_critical_init();

// Allocate args[] on the stack
char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc];

Expand Down Expand Up @@ -560,27 +556,27 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)

void runAll()
{
initSections();
gc_init();
initStaticDataGC();
rt_moduleCtor();
rt_moduleTlsCtor();
version (linux)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably copy the comment here as this is more likely the place people will look and wonder "what's going on here?"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy what comment?

{ }
else
rt_init();

if (runModuleUnitTests())
tryExec(&runMain);
else
result = EXIT_FAILURE;
rt_moduleTlsDtor();
thread_joinAll();
rt_moduleDtor();
gc_term();
finiSections();

version (linux)
{ }
else
{
if (!rt_term() && result == EXIT_SUCCESS)
result = EXIT_FAILURE;
}
}

tryExec(&runAll);

_STD_critical_term();
_STD_monitor_staticdtor();

// Issue 10344: flush stdout and return nonzero on failure
if (.fflush(.stdout) != 0)
{
Expand All @@ -593,3 +589,30 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)

return result;
}

version (linux)
{
/* Startup and shutdown is done with static construction/destruction
*/

//import core.stdc.stdio;
shared static this()
{
//printf("dmain2\n");
_STI_monitor_staticctor();
_STI_critical_init();
initSections();
gc_init();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call chain comes to early gc_init=>thread_init=>thread_attachThis=>rt.sections_linux.initTLSRanges, because it makes the implicit assumption that all libraries are already loaded. It will miss the TLS ranges from anything but libphobos2.so.

initStaticDataGC();
}

shared static ~this()
{
//printf("~dmain2\n");
//thread_joinAll();
gc_term();
finiSections();
_STD_critical_term();
_STD_monitor_staticdtor();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this really work the way we want? Since there's no dependency tree here, it seems like this static dtor will be run in a random order with the others, and so some static dtors will be run after the GC and runtime are completely shut down.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In minfo.d, I added code specifically to run this ctor first, and this dtor last.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just call rt_init within the first call to _d_dso_registry and rt_term when the last library unregisters. This is dead simple and you can scratch all the code to treat rt.dmain2 specially.

}
39 changes: 37 additions & 2 deletions src/rt/minfo.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@

module rt.minfo;

import core.stdc.stdlib; // alloca
import core.stdc.string; // memcpy
import core.stdc.stdlib;
import core.stdc.string;
import core.stdc.stdio : printf;
import rt.sections;

enum
Expand Down Expand Up @@ -46,6 +47,7 @@ struct ModuleGroup
this(ModuleInfo*[] modules)
{
_modules = modules;
first = null;
}

@property inout(ModuleInfo*)[] modules() inout
Expand Down Expand Up @@ -92,6 +94,7 @@ struct ModuleGroup
size_t cidx;

ModuleInfo*[] mods = _modules;

size_t idx;
while (true)
{
Expand Down Expand Up @@ -169,6 +172,8 @@ struct ModuleGroup
stack[stackidx++] = StackRec(mods, idx);
idx = 0;
mods = m.importedModules;
//printf("m %.*s imports:\n", m.name.length, m.name.ptr);
//foreach (m2; mods) printf("\t%.*s\n", m2.name.length, m2.name.ptr);
}
}
}
Expand All @@ -195,6 +200,18 @@ struct ModuleGroup
m.flags = m.flags & ~(MIctorstart | MIctordone);
}

/* Look for module rt.dmain2, and put that as first ctor to run
*/
foreach (m; _modules)
{
if (m.name == "rt.dmain2" && m.ctor)
{
first = m;
m.flags = m.flags | MIctordone;
break;
}
}

/* Do two passes: ctor/dtor, tlsctor/tlsdtor
*/
sort(_ctors, MIctor | MIdtor);
Expand All @@ -203,6 +220,19 @@ struct ModuleGroup

void runCtors()
{
version (none)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

version (debug_something)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to turn printf's on individually as desired. Turning on a bunch with a global flag tends to produce a blizzard of senseless output.

{
foreach (m; _modules)
printf("module %.*s\n", m.name.length, m.name.ptr);
foreach (m; _ctors)
printf("ctor %.*s\n", m.name.length, m.name.ptr);
}

if (first)
{
(*first.ctor)();
}

// run independent ctors
runModuleFuncs!(m => m.ictor)(_modules);
// sorted module ctors
Expand All @@ -225,6 +255,9 @@ struct ModuleGroup
void runDtors()
{
runModuleFuncsRev!(m => m.dtor)(_ctors);
if (first && first.dtor)
(*first.dtor)();

// clean all initialized flags
foreach (m; _modules)
m.flags = m.flags & ~MIctordone;
Expand All @@ -245,6 +278,8 @@ private:
ModuleInfo*[] _modules;
ModuleInfo*[] _ctors;
ModuleInfo*[] _tlsctors;
public:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why public I wonder

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because sections_linux.d accesses first.

ModuleInfo* first;
}


Expand Down
Loading