Skip to content

Commit

Permalink
[compiler] Unified API for multi/single threaded compilation.
Browse files Browse the repository at this point in the history
  • Loading branch information
travisdoor committed Nov 10, 2023
1 parent 7383e56 commit c164b78
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 26 deletions.
3 changes: 1 addition & 2 deletions src/assembly.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,7 @@ assembly_add_unit_safe(struct assembly *assembly, const char *filepath, struct t
unit = unit_new(filepath, load_from);
arrput(assembly->units, unit);

if (builder.options->no_jobs == false)
builder_async_submit_unit(assembly, unit);
builder_submit_unit(assembly, unit);

DONE:
pthread_spin_unlock(&sync->units_lock);
Expand Down
24 changes: 8 additions & 16 deletions src/builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ static void unit_job(struct job_context *ctx) {

static void submit_unit(struct assembly *assembly, struct unit *unit) {
bassert(unit);
bassert(builder.options->no_jobs == false);

struct job_context ctx = {
.assembly = assembly,
.unit = unit,
Expand Down Expand Up @@ -287,18 +285,14 @@ static int compile(struct assembly *assembly) {
setup_unit_pipeline(assembly);
setup_assembly_pipeline(assembly);

runtime_measure_begin(process_unit);

if (builder.options->no_jobs) {
set_single_thread_mode(builder.options->no_jobs);
if (builder.options->no_jobs)
blog("Running in single thread mode!");
for (usize i = 0; i < arrlenu(assembly->units); ++i) {
struct unit *unit = assembly->units[i];
if ((state = compile_unit(unit, assembly)) != COMPILE_OK) break;
}
} else {

{
runtime_measure_begin(process_unit);
builder.auto_submit = true;

// Compile all available units in perallel and wait for all threads to finish...
// !!! we modify original array while compiling !!!
usize len = arrlenu(assembly->units);
struct unit **dup = bmalloc(sizeof(struct unit *) * len);
Expand All @@ -311,11 +305,10 @@ static int compile(struct assembly *assembly) {
bfree(dup);
wait_threads();

builder.auto_submit = false;
builder.auto_submit = false;
assembly->stats.parsing_lexing_s = runtime_measure_end(process_unit);
}

assembly->stats.parsing_lexing_s = runtime_measure_end(process_unit);

// Compile assembly using pipeline.
if (state == COMPILE_OK) state = compile_assembly(assembly);

Expand Down Expand Up @@ -644,9 +637,8 @@ void put_tmp_str(str_buf_t str) {
arrput(storage->temporary_strings, str);
}

void builder_async_submit_unit(struct assembly *assembly, struct unit *unit) {
void builder_submit_unit(struct assembly *assembly, struct unit *unit) {
bassert(unit);
bassert(builder.options->no_jobs == false);
if (builder.auto_submit) {
submit_unit(assembly, unit);
}
Expand Down
2 changes: 1 addition & 1 deletion src/builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ s32 builder_compile_all(void);
s32 builder_compile(const struct target *target);

// Submit new unit for async compilation, in case no-jobs flag is set, this function does nothing.
void builder_async_submit_unit(struct assembly *assembly, struct unit *unit);
void builder_submit_unit(struct assembly *assembly, struct unit *unit);

#define builder_log(format, ...) builder_msg(MSG_LOG, -1, NULL, CARET_NONE, format, ##__VA_ARGS__)
#define builder_info(format, ...) builder_msg(MSG_INFO, -1, NULL, CARET_NONE, format, ##__VA_ARGS__)
Expand Down
34 changes: 27 additions & 7 deletions src/threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ static array(struct job) jobs;
static pthread_mutex_t jobs_mutex;
static pthread_cond_t jobs_cond;
static pthread_cond_t working_cond;
static s32 jobs_running = 0;
static s32 thread_count = 0;
static bool should_exit = false;
static s32 jobs_running = 0;
static s32 thread_count = 0;
static bool should_exit = false;
static bool is_single_thread = false;

static bool pop_job(struct job *job) {
s64 len = arrlen(jobs);
Expand Down Expand Up @@ -103,7 +104,8 @@ static void *worker(void UNUSED(*args)) {

void start_threads(const s32 n) {
bassert(n > 1);
thread_count = n;
thread_count = n;
is_single_thread = false;

pthread_mutex_init(&jobs_mutex, NULL);
pthread_cond_init(&jobs_cond, NULL);
Expand Down Expand Up @@ -133,6 +135,14 @@ void stop_threads(void) {
}

void wait_threads(void) {
if (is_single_thread) {
struct job job;
while (pop_job(&job)) {
job.fn(&job.ctx);
}
return;
}

pthread_mutex_lock(&jobs_mutex);
while ((!should_exit && (arrlenu(jobs) > 0 || jobs_running)) || (should_exit && thread_count != 0)) {
pthread_cond_wait(&working_cond, &jobs_mutex);
Expand All @@ -144,7 +154,9 @@ void wait_threads(void) {
}

void submit_job(job_fn_t fn, struct job_context *ctx) {
pthread_mutex_lock(&jobs_mutex);
if (!is_single_thread) {
pthread_mutex_lock(&jobs_mutex);
}
bassert(fn);
struct job *job = arraddnptr(jobs, 1);
if (ctx) {
Expand All @@ -153,8 +165,16 @@ void submit_job(job_fn_t fn, struct job_context *ctx) {
}
job->fn = fn;

pthread_cond_broadcast(&jobs_cond);
pthread_mutex_unlock(&jobs_mutex);
if (!is_single_thread) {
pthread_cond_broadcast(&jobs_cond);
pthread_mutex_unlock(&jobs_mutex);
}
}

void set_single_thread_mode(const bool is_single) {
if (is_single_thread == is_single) return;
wait_threads();
is_single_thread = is_single;
}

struct thread_local_storage *get_thread_local_storage(void) {
Expand Down
1 change: 1 addition & 0 deletions src/threading.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ void start_threads(const s32 n);
void stop_threads(void);
void wait_threads(void);
void submit_job(job_fn_t fn, struct job_context *ctx);
void set_single_thread_mode(const bool is_single);

struct thread_local_storage *get_thread_local_storage(void);
void init_thread_local_storage(void);
Expand Down

0 comments on commit c164b78

Please sign in to comment.