From: Dale Weiler Date: Sun, 18 Aug 2013 00:11:28 +0000 (+0000) Subject: Merge branch 'cooking' into threading X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=d845b8b57276126e34ee380e9602baabdbe22b58;p=xonotic%2Fgmqcc.git Merge branch 'cooking' into threading Conflicts: Makefile include.mk parser.c --- d845b8b57276126e34ee380e9602baabdbe22b58 diff --cc Makefile index cd26b16,7f9a3b1..f482de6 --- a/Makefile +++ b/Makefile @@@ -157,4 -164,4 +164,5 @@@ ir.o: gmqcc.h opts.def ir. ftepp.o: gmqcc.h opts.def lexer.h utf8.o: gmqcc.h opts.def correct.o: gmqcc.h opts.def +thread.o: gmqcc.h opts.def + fold.o: ast.h ir.h gmqcc.h opts.def parser.h lexer.h diff --cc include.mk index f83f3c0,d6d1154..bbbeb97 --- a/include.mk +++ b/include.mk @@@ -11,13 -11,13 +11,13 @@@ CC ?= clan # linker flags and optional additional libraries if required LDFLAGS += -LIBS += -lm +LIBS += -lm -lpthread #objects - OBJ_C = main.o lexer.o parser.o thread.o fs.o stat.o util.o code.o ast.o ir.o conout.o ftepp.o opts.o utf8.o correct.o -OBJ_C = main.o lexer.o parser.o fs.o stat.o util.o code.o ast.o ir.o conout.o ftepp.o opts.o utf8.o correct.o fold.o intrin.o ++OBJ_C = main.o lexer.o parser.o thread.o fs.o stat.o util.o code.o ast.o ir.o conout.o ftepp.o opts.o utf8.o correct.o fold.o intrin.o OBJ_P = util.o fs.o conout.o opts.o pak.o stat.o - OBJ_T = test.o util.o conout.o fs.o stat.o - OBJ_X = exec-standalone.o util.o conout.o fs.o stat.o + OBJ_T = test.o util.o opts.o conout.o fs.o stat.o + OBJ_X = exec-standalone.o util.o opts.o conout.o fs.o stat.o #gource flags GOURCEFLAGS = \ diff --cc opts.c index ceeb7a4,4f6660e..2b9c791 --- a/opts.c +++ b/opts.c @@@ -102,10 -130,9 +130,10 @@@ void opts_init(const char *output, int OPTS_OPTION_U32(OPTION_STANDARD) = standard; OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE) = arraysize; OPTS_OPTION_U16(OPTION_MEMDUMPCOLS) = 16; + OPTS_OPTION_U32(OPTION_J) = 2; } - static bool opts_setflag_all(const char *name, bool on, uint32_t *flags, const opts_flag_def *list, size_t listsize) { + static bool opts_setflag_all(const char *name, bool on, uint32_t *flags, const opts_flag_def_t *list, size_t listsize) { size_t i; for (i = 0; i < listsize; ++i) { diff --cc parser.c index e5dcf4d,a2ab3ca..d46dc98 --- a/parser.c +++ b/parser.c @@@ -23,92 -23,11 +23,12 @@@ */ #include #include +#include + #include "parser.h" - #include "gmqcc.h" - #include "lexer.h" - #include "ast.h" - - /* beginning of locals */ #define PARSER_HT_LOCALS 2 - - #define PARSER_HT_SIZE 128 - #define TYPEDEF_HT_SIZE 16 - - typedef struct parser_s { - lex_file *lex; - int tok; - - bool ast_cleaned; - - ast_expression **globals; - ast_expression **fields; - ast_function **functions; - ast_value **imm_float; - ast_value **imm_string; - ast_value **imm_vector; - size_t translated; - - ht ht_imm_string; - ht ht_imm_string_dotranslate; - - /* must be deleted first, they reference immediates and values */ - ast_value **accessors; - - ast_value *imm_float_zero; - ast_value *imm_float_one; - ast_value *imm_float_neg_one; - - ast_value *imm_vector_zero; - - ast_value *nil; - ast_value *reserved_version; - - size_t crc_globals; - size_t crc_fields; - - ast_function *function; - ht aliases; - - /* All the labels the function defined... - * Should they be in ast_function instead? - */ - ast_label **labels; - ast_goto **gotos; - const char **breaks; - const char **continues; - - /* A list of hashtables for each scope */ - ht *variables; - ht htfields; - ht htglobals; - ht *typedefs; - - /* same as above but for the spelling corrector */ - correct_trie_t **correct_variables; - size_t ***correct_variables_score; /* vector of vector of size_t* */ - - /* not to be used directly, we use the hash table */ - ast_expression **_locals; - size_t *_blocklocals; - ast_value **_typedefs; - size_t *_blocktypedefs; - lex_ctx *_block_ctx; - - /* we store the '=' operator info */ - const oper_info *assign_op; - - /* magic values */ - ast_value *const_vec[3]; - - /* pragma flags */ - bool noref; - - /* collected information */ - size_t max_param_count; - } parser_t; - - static ast_expression * const intrinsic_debug_typestring = (ast_expression*)0x1; + #define PARSER_HT_SIZE 512 + #define TYPEDEF_HT_SIZE 512 static void parser_enterblock(parser_t *parser); static bool parser_leaveblock(parser_t *parser); @@@ -6478,85 -5995,6 +5996,86 @@@ void parser_cleanup(parser_t *parser mem_d(parser); } +static void function_finalize_worker_do(ast_function **list, size_t count, volatile uint32_t *counter, bool *failure) +{ + do { + uint32_t idx = util_atomic_xadd32(counter, 1); + if (idx >= count) { + *counter = count; + return; + } + if (!ir_function_finalize(list[idx]->ir_func)) { + con_out("failed to finalize function %s\n", list[idx]->name); + *failure = true; + return; + } + } while (true); +} + +typedef struct { + ast_function **list; + size_t count; + volatile uint32_t *counter; + bool *failure; +} function_finalize_worker_data; +static void* function_finalize_worker(void *_d) { + function_finalize_worker_data *d = (function_finalize_worker_data*)_d; + function_finalize_worker_do(d->list, d->count, d->counter, d->failure); + return NULL; +} + +static bool function_finalize_all_threaded(ast_function **list, size_t count) +{ + volatile uint32_t counter = 0; + function_finalize_worker_data wd; + + size_t poolsize = OPTS_OPTION_U32(OPTION_J); + bool failure = false; + size_t i, j; + + pthread_t *threads; + + if (!list || !count) + return true; + + wd.list = list; + wd.count = count; + wd.counter = &counter; + wd.failure = &failure; + + threads = (pthread_t*)mem_a(poolsize*sizeof(pthread_t)); + + for (i = 0; i < poolsize; ++i) { + if (pthread_create(threads+i, NULL, &function_finalize_worker, &wd) != 0) + break; + } + if (i < poolsize) { + con_out("failed to spawn worker threads\n"); + for (j = 0; j <= i; ++j) + pthread_join(threads[j], NULL); + return false; + } + for (i = 0; i < poolsize; ++i) + pthread_join(threads[i], NULL); + return !failure; +} + ++bool function_finalize_all(ast_function **list, size_t count); +bool function_finalize_all(ast_function **list, size_t count) +{ + size_t i; + if (OPTS_OPTION_U32(OPTION_J) > 1) + return function_finalize_all_threaded(list, count); + + for (i = 0; i < count; ++i) { + if (!ir_function_finalize(list[i]->ir_func)) { + con_out("failed to finalize function %s\n", list[i]->name); + return false; + } + } + return true; +} + bool parser_finish(parser_t *parser, const char *output) { size_t i;