Skip to content

Commit

Permalink
WIP: threading without LLVM patch
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao committed Nov 21, 2015
1 parent 1b84ecb commit 393bddc
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 54 deletions.
8 changes: 4 additions & 4 deletions Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,10 @@ DISABLE_ASSERTIONS := -DNDEBUG
endif

# Threads
ifeq ($(JULIA_THREADS), 1)
LLVM_VER := svn
LLVM_GIT_URL_LLVM := https://github.com/JuliaLang/llvm.git -b jn/tls37
endif
# ifeq ($(JULIA_THREADS), 1)
# LLVM_VER := svn
# LLVM_GIT_URL_LLVM := https://github.com/JuliaLang/llvm.git -b jn/tls37
# endif

# Compiler specific stuff

Expand Down
21 changes: 19 additions & 2 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2124,12 +2124,29 @@ static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **arg
}
}

static Value *emit_ptls_states()
{
#ifndef JULIA_ENABLE_THREADING
return builder.CreateBitCast(prepare_global(jltls_states_var), T_ppint8);
#else
return builder.CreateCall(prepare_call(jltls_states_func));
#endif
}

static Value *emit_pgcstack()
{
return prepare_global(jlpgcstack_var);
Value * addr = emit_nthptr_addr(
emit_ptls_states(),
(ssize_t)(offsetof(jl_tls_states_t, pgcstack) / sizeof(void*)));
return builder.CreateBitCast(addr, PointerType::get(T_ppjlvalue, 0),
"jl_pgcstack");
}

static Value *emit_exc_in_transit()
{
return prepare_global(jlexc_var);
Value * addr = emit_nthptr_addr(
emit_ptls_states(),
(ssize_t)(offsetof(jl_tls_states_t,
exception_in_transit) / sizeof(void*)));
return builder.CreateBitCast(addr, T_ppjlvalue, "jl_exception_in_transit");
}
44 changes: 25 additions & 19 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,6 @@ static GlobalVariable *jlemptytuple_var;
#ifdef JL_NEED_FLOATTEMP_VAR
static GlobalVariable *jlfloattemp_var;
#endif
static GlobalVariable *jlpgcstack_var;
static GlobalVariable *jlexc_var;
static GlobalVariable *jldiverr_var;
static GlobalVariable *jlundeferr_var;
static GlobalVariable *jldomerr_var;
Expand All @@ -467,6 +465,12 @@ extern JITMemoryManager* createJITMemoryManagerWin();
extern RTDyldMemoryManager* createRTDyldMemoryManagerOSX();
#endif

#ifndef JULIA_ENABLE_THREADING
static GlobalVariable *jltls_states_var;
#else
static Function *jltls_states_func;
#endif

// important functions
static Function *jlnew_func;
static Function *jlthrow_func;
Expand Down Expand Up @@ -5574,23 +5578,6 @@ static void init_julia_llvm_env(Module *m)
"jl_array_t");
jl_parray_llvmt = PointerType::get(jl_array_llvmt,0);

#ifdef JULIA_ENABLE_THREADING
#define JL_THREAD_MODEL ,GlobalValue::GeneralDynamicTLSModel
#else
#define JL_THREAD_MODEL
#endif
jlpgcstack_var =
new GlobalVariable(*m, T_ppjlvalue,
false, GlobalVariable::ExternalLinkage,
NULL, "jl_pgcstack", NULL JL_THREAD_MODEL);
add_named_global(jlpgcstack_var, jl_dlsym(jl_dl_handle, "jl_pgcstack"));

jlexc_var =
new GlobalVariable(*m, T_pjlvalue,
false, GlobalVariable::ExternalLinkage,
NULL, "jl_exception_in_transit", NULL JL_THREAD_MODEL);
add_named_global(jlexc_var, jl_dlsym(jl_dl_handle, "jl_exception_in_transit"));

global_to_llvm("__stack_chk_guard", (void*)&__stack_chk_guard, m);
Function *jl__stack_chk_fail =
Function::Create(FunctionType::get(T_void, false),
Expand Down Expand Up @@ -5640,6 +5627,25 @@ static void init_julia_llvm_env(Module *m)
"jl_float_temp"));
#endif

#ifndef JULIA_ENABLE_THREADING
jltls_states_var =
new GlobalVariable(*m, ArrayType::get(T_int8, sizeof(jl_tls_states_t)),
false, GlobalVariable::ExternalLinkage,
NULL, "jl_tls_states");
add_named_global(jltls_states_var, (void*)&jl_tls_states);
#else
jltls_states_func = Function::Create(FunctionType::get(T_ppint8, false),
Function::ExternalLinkage,
"jl_get_ptls_states", m);
jltls_states_func->setAttributes(
jltls_states_func->getAttributes()
.addAttribute(jltls_states_func->getContext(),
AttributeSet::FunctionIndex, Attribute::ReadNone)
.addAttribute(jltls_states_func->getContext(),
AttributeSet::FunctionIndex, Attribute::NoUnwind));
add_named_global(jltls_states_func, (void*)&jl_get_ptls_states);
#endif

std::vector<Type*> args1(0);
args1.push_back(T_pint8);
jlerror_func =
Expand Down
2 changes: 1 addition & 1 deletion src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ typedef struct {
// In the single-threaded version, they are essentially noops, but nonetheless
// serve to check that the thread context macros are being used.
#ifdef JULIA_ENABLE_THREADING
static JL_THREAD jl_thread_heap_t *jl_thread_heap;
#define jl_thread_heap (*(jl_thread_heap_t**)&(jl_get_ptls_states()->heap))
#define FOR_EACH_HEAP() \
for (jl_each_heap_index_t __current_heap_idx = {jl_n_threads, NULL}; \
--current_heap_index >= 0 && \
Expand Down
39 changes: 23 additions & 16 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,6 @@ extern "C" {
// JULIA_ENABLE_THREADING is switched on in Make.inc if JULIA_THREADS is
// set (in Make.user)

#ifndef JULIA_ENABLE_THREADING
// Definition for compiling non-thread-safe Julia.
# define JL_THREAD
#elif !defined(_OS_WINDOWS_)
// Definition for compiling Julia on platforms with GCC __thread.
# define JL_THREAD __thread
#else
// Definition for compiling Julia on Windows
# define JL_THREAD __declspec(thread)
#endif

DLLEXPORT int16_t jl_threadid(void);
DLLEXPORT void *jl_threadgroup(void);
DLLEXPORT void jl_cpu_pause(void);
Expand Down Expand Up @@ -585,7 +574,7 @@ typedef struct _jl_gcframe_t {
// jl_value_t *x=NULL, *y=NULL; JL_GC_PUSH2(&x, &y);
// x = f(); y = g(); foo(x, y)

extern DLLEXPORT JL_THREAD jl_gcframe_t *jl_pgcstack;
#define jl_pgcstack (jl_get_ptls_states()->pgcstack)

#define JL_GC_PUSH1(arg1) \
void *__gc_stkf[] = {(void*)3, jl_pgcstack, arg1}; \
Expand Down Expand Up @@ -1485,17 +1474,35 @@ typedef struct {
jl_value_t * volatile *ptask_arg_in_transit;
} jl_thread_task_state_t;

extern DLLEXPORT JL_THREAD jl_task_t * volatile jl_current_task;
extern DLLEXPORT JL_THREAD jl_task_t *jl_root_task;
extern DLLEXPORT JL_THREAD jl_value_t *jl_exception_in_transit;
extern DLLEXPORT JL_THREAD jl_value_t * volatile jl_task_arg_in_transit;
#define jl_current_task (jl_get_ptls_states()->current_task)
#define jl_root_task (jl_get_ptls_states()->root_task)
#define jl_exception_in_transit (jl_get_ptls_states()->exception_in_transit)
#define jl_task_arg_in_transit (jl_get_ptls_states()->task_arg_in_transit)

DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, size_t ssize);
DLLEXPORT jl_value_t *jl_switchto(jl_task_t *t, jl_value_t *arg);
DLLEXPORT void NORETURN jl_throw(jl_value_t *e);
DLLEXPORT void NORETURN jl_rethrow(void);
DLLEXPORT void NORETURN jl_rethrow_other(jl_value_t *e);

typedef struct _jl_tls_states_t {
jl_gcframe_t *pgcstack;
jl_value_t *exception_in_transit;
void *heap;
jl_task_t *volatile current_task;
jl_task_t *root_task;
jl_value_t *volatile task_arg_in_transit;
void *stackbase;
jl_jmp_buf *volatile jmp_target;
jl_jmp_buf base_ctx; // base context of stack
int16_t tid;
} jl_tls_states_t;
DLLEXPORT JL_CONST_FUNC jl_tls_states_t *(jl_get_ptls_states)(void);
#ifndef JULIA_ENABLE_THREADING
extern DLLEXPORT jl_tls_states_t jl_tls_states;
#define jl_get_ptls_states() (&jl_tls_states)
#endif

STATIC_INLINE void jl_eh_restore_state(jl_handler_t *eh)
{
JL_SIGATOMIC_BEGIN();
Expand Down
2 changes: 1 addition & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ void jl_init_serializer(void);

void _julia_init(JL_IMAGE_SEARCH rel);
#ifdef COPY_STACKS
extern JL_THREAD void *jl_stackbase;
#define jl_stackbase (jl_get_ptls_states()->stackbase)
#endif

void jl_set_stackbase(char *__stk);
Expand Down
11 changes: 3 additions & 8 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,17 @@ static jl_sym_t *runnable_sym;

extern size_t jl_page_size;
jl_datatype_t *jl_task_type;
DLLEXPORT JL_THREAD jl_task_t * volatile jl_current_task;
JL_THREAD jl_task_t *jl_root_task;
DLLEXPORT JL_THREAD jl_value_t *jl_exception_in_transit;
DLLEXPORT JL_THREAD jl_gcframe_t *jl_pgcstack = NULL;
#define jl_root_task (jl_get_ptls_states()->root_task)

#ifdef COPY_STACKS
static JL_THREAD jl_jmp_buf * volatile jl_jmp_target;
#define jl_jmp_target (jl_get_ptls_states()->jmp_target)

#if (defined(_CPU_X86_64_) || defined(_CPU_X86_)) && !defined(_COMPILER_MICROSOFT_)
#define ASM_COPY_STACKS
#endif
JL_THREAD void *jl_stackbase;

#ifndef ASM_COPY_STACKS
static JL_THREAD jl_jmp_buf jl_base_ctx; // base context of stack
#define jl_base_ctx (jl_get_ptls_states()->base_ctx)
#endif

static void NOINLINE save_stack(jl_task_t *t)
Expand Down Expand Up @@ -359,7 +355,6 @@ static void ctx_switch(jl_task_t *t, jl_jmp_buf *where)
//JL_SIGATOMIC_END();
}

JL_THREAD jl_value_t * volatile jl_task_arg_in_transit;
extern int jl_in_gc;
DLLEXPORT jl_value_t *jl_switchto(jl_task_t *t, jl_value_t *arg)
{
Expand Down
19 changes: 18 additions & 1 deletion src/threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,25 @@ extern "C" {
#include "threadgroup.h"
#include "threading.h"

#ifdef JULIA_ENABLE_THREADING
# if !defined(_COMPILER_MICROSOFT_)
// Definition for compiling Julia on platforms with GCC __thread.
# define JL_THREAD __thread
# else
// Definition for compiling Julia on Windows
# define JL_THREAD __declspec(thread)
# endif
JL_THREAD jl_tls_states_t jl_tls_states;
#else
DLLEXPORT jl_tls_states_t jl_tls_states;
#endif

DLLEXPORT JL_CONST_FUNC jl_tls_states_t *(jl_get_ptls_states)(void)
{
return &jl_tls_states;
}

// thread ID
JL_THREAD int16_t ti_tid = 0;
DLLEXPORT int jl_n_threads; // # threads we're actually using
DLLEXPORT int jl_max_threads; // # threads possible
jl_thread_task_state_t *jl_all_task_states;
Expand Down
3 changes: 1 addition & 2 deletions src/threading.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern "C" {
#define PROFILE_JL_THREADING 1

// thread ID
extern JL_THREAD int16_t ti_tid;
#define ti_tid (jl_get_ptls_states()->tid)
extern jl_thread_task_state_t *jl_all_task_states;
extern DLLEXPORT int jl_n_threads; // # threads we're actually using

Expand Down Expand Up @@ -69,4 +69,3 @@ jl_value_t *ti_runthread(jl_function_t *f, jl_svec_t *args, size_t nargs);
#endif

#endif /* THREADING_H */

0 comments on commit 393bddc

Please sign in to comment.