Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

druntime: replaces top level version(..) branching by tags #15887

Closed
wants to merge 2 commits into from
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
51 changes: 48 additions & 3 deletions druntime/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,47 @@ DRUNTIMESOLIB=$(DRUNTIMESO)$(DOTLIB)

STDDOC=

###############

TAGGED_COPY_LIST_FILE:=mak/TAGGED_COPY
TAGGED_SRCS_FILE:=$(ROOT)/GEN_SRCS
TAGGED_COPY_FILE:=$(ROOT)/GEN_COPY

ifeq (windows,$(OS))
# Tags order doesn't matter
TAGS:=windows
else
TAGS:=$(OS),posix_threads
endif

TGEN_CMD:=./parse_tagged_hier.d $(TAGGED_SRCS_FILE) $(TAGGED_COPY_LIST_FILE) $(TAGGED_COPY_FILE) $(IMPDIR) $(TAGS) config > /dev/null

TAGGED_SRCS:=$(shell $(TGEN_CMD) && cat $(TAGGED_SRCS_FILE))

# MacOS doesn't support .SHELLSTATUS
ifneq ($(.SHELLSTATUS),)
ifneq ($(.SHELLSTATUS),0)
$(error Tagged sources list generation failed)
endif
endif

TAGGED_COPY:=$(shell $(TGEN_CMD) && cat $(TAGGED_COPY_FILE))
ifneq ($(.SHELLSTATUS),)
ifneq ($(.SHELLSTATUS),0)
$(error Tagged copy list generation failed)
endif
endif

###############

include mak/COPY
COPY:=$(subst \,/,$(COPY))
COPY:=$(subst \,/,$(COPY)) $(subst \,/,$(TAGGED_COPY))

include mak/DOCS
DOCS:=$(subst \,/,$(DOCS))

include mak/SRCS
SRCS:=$(subst \,/,$(SRCS))
SRCS:=$(subst \,/,$(SRCS)) $(subst \,/,$(TAGGED_SRCS))

# NOTE: trace.d and cover.d are not necessary for a successful build
# as both are used for debugging features (profiling and coverage)
Expand Down Expand Up @@ -352,6 +385,13 @@ import: copy

copy: $(COPY)

strip_first_dirs:=cut -d '/' -f4-
IMP_PATH=$(IMPDIR)/$(shell echo $@ | $(strip_first_dirs))

$(IMPDIR)/config/%.d : config/%.d
@mkdir -p $(dir $(IMP_PATH))
@cp $< $(IMP_PATH)

$(IMPDIR)/%.di : src/%.di
@mkdir -p $(dir $@)
@cp $< $@
Expand Down Expand Up @@ -395,6 +435,11 @@ $(ROOT)/valgrind$(DOTOBJ) : src/etc/valgrind/valgrind.c src/etc/valgrind/valgrin
@mkdir -p `dirname $@`
$(CC) -c $(CFLAGS) $< -o$@

################################################

gen_tagged_srcs_clean:
rm -f $(TAGGED_SRCS_FILE) $(TAGGED_SRCS_FILE).disabled $(TAGGED_COPY_FILE)

######################## Create a shared library ##############################

$(DRUNTIMESO) $(DRUNTIMESOLIB) dll: DFLAGS+=-version=Shared $(SHAREDFLAGS)
Expand Down Expand Up @@ -550,7 +595,7 @@ install: target
cp -r import/* '$(INSTALL_DIR)'/src/druntime/import/
endif

clean: $(addsuffix /.clean,$(ADDITIONAL_TESTS))
clean: $(addsuffix /.clean,$(ADDITIONAL_TESTS)) gen_tagged_srcs_clean
rm -rf $(ROOT_OF_THEM_ALL) $(IMPDIR) $(DOC_OUTPUT_DIR) druntime.zip

%/.directory :
Expand Down
115 changes: 115 additions & 0 deletions druntime/config/posix_threads/core/sync/event_impl.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
module core.sync.event_impl;

import core.internal.abort : abort;
import core.sys.posix.pthread;
import core.sys.posix.sys.types;
import core.sys.posix.time;
import core.time;

package:

nothrow @nogc:

struct EventHandler
{
pthread_mutex_t m_mutex;
pthread_cond_t m_cond;
bool initalized;
bool m_state;
bool m_manualReset;
}

EventHandler create(bool manualReset, bool initialState)
{
EventHandler h;

pthread_mutex_init(cast(pthread_mutex_t*) &(h.m_mutex), null) == 0 ||
abort("Error: pthread_mutex_init failed.");

static if ( is( typeof( pthread_condattr_setclock ) ) )
{
pthread_condattr_t attr = void;
pthread_condattr_init(&attr) == 0 ||
abort("Error: pthread_condattr_init failed.");
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0 ||
abort("Error: pthread_condattr_setclock failed.");
pthread_cond_init(&(h.m_cond), &attr) == 0 ||
abort("Error: pthread_cond_init failed.");
pthread_condattr_destroy(&attr) == 0 ||
abort("Error: pthread_condattr_destroy failed.");
}
else
{
pthread_cond_init(&(h.m_cond), null) == 0 ||
abort("Error: pthread_cond_init failed.");
}

h.m_state = initialState;
h.m_manualReset = manualReset;
h.initalized = true;

return h;
}

void destroy(ref EventHandler h)
{
pthread_mutex_destroy(&(h.m_mutex)) == 0 ||
abort("Error: pthread_mutex_destroy failed.");

pthread_cond_destroy(&(h.m_cond)) == 0 ||
abort("Error: pthread_cond_destroy failed.");

h.initalized = false;
}

void set(ref EventHandler h)
{
h.mutexLock;
h.m_state = true;
pthread_cond_broadcast(&(h.m_cond));
h.mutexUnlock;
}

void reset(ref EventHandler h)
{
h.mutexLock;
h.m_state = false;
h.mutexUnlock;
}

bool wait(ref EventHandler h)
{
return h.wait(Duration.max);
}

bool wait(ref EventHandler h, Duration tmout)
{
h.mutexLock;

int result = 0;
if (!h.m_state)
{
if (tmout == Duration.max)
{
result = pthread_cond_wait(&(h.m_cond), &(h.m_mutex));
}
else
{
import core.sync.config;

timespec t = void;
mktspec(t, tmout);

result = pthread_cond_timedwait(&(h.m_cond), &(h.m_mutex), &t);
}
}
if (result == 0 && !h.m_manualReset)
h.m_state = false;

h.mutexUnlock;

return result == 0;
}

private void mutexLock(ref EventHandler h) { pthread_mutex_lock(&(h.m_mutex)); }
private void mutexUnlock(ref EventHandler h) { pthread_mutex_unlock(&(h.m_mutex)); }
60 changes: 60 additions & 0 deletions druntime/config/windows/core/sync/event_impl.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module core.sync.event_impl;

import core.internal.abort : abort;
import core.sys.windows.basetsd /+: HANDLE +/;
import core.sys.windows.winerror /+: WAIT_TIMEOUT +/;
import core.sys.windows.winbase /+: CreateEvent, CloseHandle, SetEvent, ResetEvent,
WaitForSingleObject, INFINITE, WAIT_OBJECT_0+/;
import core.time;

package:

nothrow @nogc:

alias EventHandler = HANDLE;

bool initalized(in EventHandler h) { return h !is null; }

EventHandler create(bool manualReset, bool initialState)
{
HANDLE m_event = CreateEvent(null, manualReset, initialState, null);
m_event || abort("Error: CreateEvent failed.");

return m_event;
}

void destroy(ref EventHandler m_event)
{
CloseHandle(m_event);
m_event = null;
}

void set(EventHandler m_event)
{
SetEvent(m_event);
}

void reset(EventHandler m_event)
{
ResetEvent(m_event);
}

bool wait(EventHandler m_event)
{
return m_event && WaitForSingleObject(m_event, INFINITE) == WAIT_OBJECT_0;
}

bool wait(EventHandler m_event, Duration tmout)
{
auto maxWaitMillis = dur!("msecs")(uint.max - 1);

while (tmout > maxWaitMillis)
{
auto res = WaitForSingleObject(m_event, uint.max - 1);
if (res != WAIT_TIMEOUT)
return res == WAIT_OBJECT_0;
tmout -= maxWaitMillis;
}
auto ms = cast(uint)(tmout.total!"msecs");
return WaitForSingleObject(m_event, ms) == WAIT_OBJECT_0;
}
1 change: 1 addition & 0 deletions druntime/mak/TAGGED_COPY
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
core\sync\event_impl.d
117 changes: 117 additions & 0 deletions druntime/parse_tagged_hier.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env dub
/+
dub.sdl:
name "parse_tagged_hier"
+/

import std.algorithm;
import std.array;
import std.conv: to;
import std.file;
import std.exception: enforce;
import std.path;
import std.stdio;
import std.string: splitLines;
import std.typecons;

int main(in string[] args)
{
try
worker(args);
catch(Exception e)
{
stderr.writeln("Error: "~e.msg);
return 1;
}

return 0;
}

void worker(in string[] args)
{
enforce(args.length >= 7 && args.length <= 8, "need 6 or 7 CLI arguments");

immutable dstFile = args[1].buildNormalizedPath; /// i.e. GEN_SRCS file
immutable taggedImportsFile = args[2].buildNormalizedPath; /// i.e. mak/TAGGED_COPY
immutable dstCopyFile = args[3].buildNormalizedPath; /// i.e. GEN_COPY file, generated list of imports choised by tags
immutable impDir = args[4].buildNormalizedPath; /// path to druntime ./import/ dir
immutable tagsArg = args[5]; /// comma separated list of tags
immutable configDir = args[6]; /// path to druntime config/ dir where is placed tags implementations
immutable externalConfigDir = (args.length > 7) ? args[7] : null; /// path to additional (external) config/ dir

enforce(taggedImportsFile.isFile, `Tagged imports file '`~taggedImportsFile~`' not found`);
enforce(configDir.isDir, `Tags implementations dir '`~configDir~`' not found`);

if(externalConfigDir !is null)
enforce(externalConfigDir.isDir, `Additional tags dir '`~externalConfigDir~`' not found`);

immutable string[] tags = tagsArg.split(",");

writeln("Tags will be applied: ", tagsArg);

immutable allConfigDirs = [configDir, externalConfigDir];

auto availTagsDirs = allConfigDirs
.map!(a => a.dirEntries(SpanMode.shallow))
.join
.filter!(a => a.isDir)
.map!(a => Tuple!(string, "base", string, "path")(a.name.baseName, a.name))
.array
.sort!((a, b) => a.base < b.base);

static struct SrcElem
{
string basePath; // ~/a/b/c/confing_dir/tag_1_name
string tag; // tag_1_name
string relPath; // core/internal/somemodule.d

string fullPath() const
{
return basePath~"/"~relPath; // ~/a/b/c/confing_dir/tag_1_name/core/internal/somemodule.d
}
}

SrcElem[] resultSrcsList;

foreach(tag; tags)
{
auto foundSUbdirs = availTagsDirs.filter!(a => a.base == tag);

if(foundSUbdirs.empty)
{
stderr.writeln(`Warning: tag '`, tag, `' doesn't corresponds to any subdirectory inside of '`, allConfigDirs,`', skip`);
continue;
}

// tag matched, files from matching dirs should be added to list recursively
auto filesToAdd = foundSUbdirs.map!(
d => dirEntries(d.path, SpanMode.depth)
.filter!(a => a.isFile)
.map!(e => SrcElem(d.path, tag, e.name[d.path.length+1 .. $]))
).join;

foreach(f; filesToAdd)
{
auto found = resultSrcsList.find!((a, b) => a.relPath == b.relPath)(f);

enforce(found.empty, `File '`~f.fullPath~`' overrides already defined file '`~found.front.fullPath~`'`);

resultSrcsList ~= f;
}
}

auto taggedImportsList = taggedImportsFile.readText.replace(`\`, `/`).splitLines.sort.uniq.array;
auto importsToCopy = File(dstCopyFile, "w");

foreach(imp; taggedImportsList)
{
auto found = resultSrcsList.find!(a => a.relPath == imp);
enforce(!found.empty, `Required for import file '`~imp~`' is not found in tagged sources`);

importsToCopy.writeln(found.front.fullPath);
}

resultSrcsList.map!(a => a.fullPath).join("\n").toFile(dstFile);

writeln("All tags applied");
}
Loading
Loading