Skip to content

Commit

Permalink
Don't use pthread_*_np functions to get stack master thread
Browse files Browse the repository at this point in the history
They seems to return bogus values for master thread on Linux and possibly OSX.
  • Loading branch information
yuyichao committed Dec 29, 2015
1 parent b1a2d54 commit 90db5bd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 43 deletions.
85 changes: 44 additions & 41 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,46 +88,10 @@ jl_options_t jl_options = { 0, // quiet
int jl_boot_file_loaded = 0;
size_t jl_page_size;

void jl_init_stack_limits(void)
void jl_init_stack_limits(int ismaster)
{
#if defined(_OS_LINUX_)
pthread_attr_t attr;
if (pthread_getattr_np(pthread_self(), &attr)) {
// On linux `pthread_getattr_np` can fail on master thread if
// `/proc/self/maps` is not readable, in which case we fall back to
// `rlimit`
struct rlimit rl;
getrlimit(RLIMIT_STACK, &rl);
jl_stack_hi = (char*)&attr;
jl_stack_lo = jl_stack_hi - rl.rlim_cur;
}
else {
void *stackaddr;
size_t stacksize;
pthread_attr_getstack(&attr, &stackaddr, &stacksize);
pthread_attr_destroy(&attr);
jl_stack_lo = (char*)stackaddr;
jl_stack_hi = (char*)stackaddr + stacksize;
}
#elif defined(_OS_DARWIN_)
extern void *pthread_get_stackaddr_np(pthread_t thread);
extern size_t pthread_get_stacksize_np(pthread_t thread);
pthread_t thread = pthread_self();
void *stackaddr = pthread_get_stackaddr_np(thread);
size_t stacksize = pthread_get_stacksize_np(thread);
jl_stack_lo = (char*)stackaddr;
jl_stack_hi = (char*)stackaddr + stacksize;
#elif defined(_OS_FREEBSD_)
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_get_np(pthread_self(), &attr);
void *stackaddr;
size_t stacksize;
pthread_attr_getstack(&attr, &stackaddr, &stacksize);
pthread_attr_destroy(&attr);
jl_stack_lo = (char*)stackaddr;
jl_stack_hi = (char*)stackaddr + stacksize;
#elif defined(_OS_WINDOWS_)
#ifdef _OS_WINDOWS_
(void)ismaster;
# ifdef _COMPILER_MICROSOFT_
# ifdef _P64
void **tib = (void**)__readgsqword(0x30);
Expand All @@ -147,7 +111,46 @@ void jl_init_stack_limits(void)
jl_stack_lo = (char*)tib[2]; // Stack Limit / Ceiling of stack (low address)
#else
# ifdef JULIA_ENABLE_THREADING
# warning "Getting stack size for thread is not supported."
// Only use pthread_*_np functions to get stack address for non-master
// threads since it seems to return bogus values for master thread on Linux
// and possibly OSX.
if (!ismaster) {
# if defined(_OS_LINUX_)
pthread_attr_t attr;
pthread_getattr_np(pthread_self(), &attr);
void *stackaddr;
size_t stacksize;
pthread_attr_getstack(&attr, &stackaddr, &stacksize);
pthread_attr_destroy(&attr);
jl_stack_lo = (char*)stackaddr;
jl_stack_hi = (char*)stackaddr + stacksize;
return;
# elif defined(_OS_DARWIN_)
extern void *pthread_get_stackaddr_np(pthread_t thread);
extern size_t pthread_get_stacksize_np(pthread_t thread);
pthread_t thread = pthread_self();
void *stackaddr = pthread_get_stackaddr_np(thread);
size_t stacksize = pthread_get_stacksize_np(thread);
jl_stack_lo = (char*)stackaddr;
jl_stack_hi = (char*)stackaddr + stacksize;
return;
# elif defined(_OS_FREEBSD_)
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_get_np(pthread_self(), &attr);
void *stackaddr;
size_t stacksize;
pthread_attr_getstack(&attr, &stackaddr, &stacksize);
pthread_attr_destroy(&attr);
jl_stack_lo = (char*)stackaddr;
jl_stack_hi = (char*)stackaddr + stacksize;
return;
# else
# warning "Getting stack size for thread is not supported."
# endif
}
# else
(void)ismaster;
# endif
struct rlimit rl;
getrlimit(RLIMIT_STACK, &rl);
Expand Down Expand Up @@ -180,7 +183,7 @@ static void jl_find_stack_bottom(void)
}
#endif
#endif
jl_init_stack_limits();
jl_init_stack_limits(1);
}

struct uv_shutdown_queue_item { uv_handle_t *h; struct uv_shutdown_queue_item *next; };
Expand Down
2 changes: 1 addition & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void jl_init_primitives(void);
void jl_init_codegen(void);
void jl_init_intrinsic_functions(void);
void jl_init_tasks(void);
void jl_init_stack_limits(void);
void jl_init_stack_limits(int ismaster);
void jl_init_root_task(void *stack, size_t ssize);
void jl_init_serializer(void);
void jl_gc_init(void);
Expand Down
2 changes: 1 addition & 1 deletion src/threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ void ti_threadfun(void *arg)

// initialize this thread (set tid, create heap, etc.)
ti_initthread(ta->tid);
jl_init_stack_limits();
jl_init_stack_limits(0);

// set up tasking
jl_init_root_task(jl_stack_lo, jl_stack_hi - jl_stack_lo);
Expand Down

0 comments on commit 90db5bd

Please sign in to comment.