int main(void) { pthread_attr_t attr; int rc; /* Initialize attr */ rc = pthread_attr_init(&attr); if (rc != 0) { perror(ERROR_PREFIX "pthread_attr_init"); exit(PTS_UNRESOLVED); } /* Get the default stack_addr and stack_size value */ rc = pthread_attr_getstack(&attr, &stack_addr, &stack_size); if (rc != 0) { perror(ERROR_PREFIX "pthread_attr_getstack"); exit(PTS_UNRESOLVED); } /* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size); */ stack_size = PTHREAD_STACK_MIN; if (posix_memalign(&stack_addr, sysconf(_SC_PAGE_SIZE), stack_size) != 0) { perror(ERROR_PREFIX "out of memory while " "allocating the stack memory"); exit(PTS_UNRESOLVED); } stack_addr = stack_addr + OFFSET; /* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size); */ rc = pthread_attr_setstack(&attr, stack_addr, stack_size); if (rc != EINVAL) { printf("The function didn't fail when stackaddr " "lacks proper alignment\n"); } stack_addr = stack_addr + OFFSET; stack_size = PTHREAD_STACK_MIN + OFFSET; /* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size); */ rc = pthread_attr_setstack(&attr, stack_addr, stack_size); if (rc != EINVAL) { printf("The function didn't fail when (stackaddr + stacksize) " "lacks proper alignment\n"); } rc = pthread_attr_destroy(&attr); if (rc != 0) { perror(ERROR_PREFIX "pthread_attr_destroy"); exit(PTS_UNRESOLVED); } printf("Test PASSED\n"); return PTS_PASS; }
void *nativeStackBase() { pthread_attr_t attr; size_t size; void *addr; pthread_attr_init(&attr); pthread_attr_get_np(pthread_self(), &attr); pthread_attr_getstack(&attr, &addr, &size); return addr+size; }
void mono_threads_core_get_stack_bounds (guint8 **staddr, size_t *stsize) { pthread_attr_t attr; *staddr = NULL; *stsize = (size_t)-1; pthread_getattr_np (pthread_self (), &attr); pthread_attr_getstack (&attr, (void**)staddr, stsize); pthread_attr_destroy (&attr); }
static void pthread_attr_getstack_18908062_helper(void*) { char local_variable; pthread_attr_t attributes; pthread_getattr_np(pthread_self(), &attributes); void* stack_base; size_t stack_size; pthread_attr_getstack(&attributes, &stack_base, &stack_size); // Test whether &local_variable is in [stack_base, stack_base + stack_size). ASSERT_LE(reinterpret_cast<char*>(stack_base), &local_variable); ASSERT_LT(&local_variable, reinterpret_cast<char*>(stack_base) + stack_size); }
STATUS taskGetInfo(TASK_ID task_id, TASK_DESC *desc) { int vfirst, vlast, ret; struct wind_task *task; struct WIND_TCB *tcb; pthread_attr_t attr; size_t stacksize; void *stackbase; task = get_wind_task(task_id); if (task == NULL) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } tcb = task->tcb; desc->td_tid = task_id; desc->td_priority = wind_task_get_priority(task); desc->td_status = get_task_status(task); desc->td_flags = tcb->flags; strncpy(desc->td_name, task->name, sizeof(desc->td_name)); desc->td_entry = tcb->entry; desc->td_errorStatus = *task->thobj.errno_pointer; ret = pthread_getattr_np(task->thobj.tid, &attr); put_wind_task(task); /* * If the target does not support pthread_getattr_np(), we are * out of luck for determining the stack information. We just * zero it. */ if (ret) { /* No idea, buddy. */ desc->td_stacksize = 0; desc->td_pStackBase = NULL; } else { pthread_attr_getstack(&attr, &stackbase, &stacksize); desc->td_stacksize = stacksize; desc->td_pStackBase = stackbase; if (&vfirst < &vlast) /* Stack grows upward. */ desc->td_pStackEnd = (caddr_t)stackbase + stacksize; else /* Stack grows downward. */ desc->td_pStackEnd = (caddr_t)stackbase - stacksize; } return OK; }
static int get_stack(void **addr, size_t *size) { #define CHECK_ERR(expr) \ {int err = (expr); if (err) return err;} #if defined HAVE_PTHREAD_GETATTR_NP || defined HAVE_PTHREAD_ATTR_GET_NP pthread_attr_t attr; size_t guard = 0; # ifdef HAVE_PTHREAD_GETATTR_NP CHECK_ERR(pthread_getattr_np(pthread_self(), &attr)); # ifdef HAVE_PTHREAD_ATTR_GETSTACK CHECK_ERR(pthread_attr_getstack(&attr, addr, size)); # else CHECK_ERR(pthread_attr_getstackaddr(&attr, addr)); CHECK_ERR(pthread_attr_getstacksize(&attr, size)); # endif if (pthread_attr_getguardsize(&attr, &guard) == 0) { STACK_GROW_DIR_DETECTION; STACK_DIR_UPPER((void)0, *addr = (char *)*addr + guard); *size -= guard; } # else CHECK_ERR(pthread_attr_init(&attr)); CHECK_ERR(pthread_attr_get_np(pthread_self(), &attr)); CHECK_ERR(pthread_attr_getstackaddr(&attr, addr)); CHECK_ERR(pthread_attr_getstacksize(&attr, size)); # endif CHECK_ERR(pthread_attr_getguardsize(&attr, &guard)); # ifndef HAVE_PTHREAD_GETATTR_NP pthread_attr_destroy(&attr); # endif size -= guard; #elif defined HAVE_PTHREAD_GET_STACKADDR_NP && defined HAVE_PTHREAD_GET_STACKSIZE_NP pthread_t th = pthread_self(); *addr = pthread_get_stackaddr_np(th); *size = pthread_get_stacksize_np(th); #elif defined HAVE_THR_STKSEGMENT || defined HAVE_PTHREAD_STACKSEG_NP stack_t stk; # if defined HAVE_THR_STKSEGMENT CHECK_ERR(thr_stksegment(&stk)); # else CHECK_ERR(pthread_stackseg_np(pthread_self(), &stk)); # endif *addr = stk.ss_sp; *size = stk.ss_size; #endif return 0; #undef CHECK_ERR }
void *nativeStackBase() { #if defined(__UCLIBC__) || defined(__EMSCRIPTEN__) return NULL; #else pthread_attr_t attr; void *addr; size_t size; pthread_getattr_np(pthread_self(), &attr); pthread_attr_getstack(&attr, &addr, &size); return addr+size; #endif }
static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs) { #if OS(DARWIN) #if __DARWIN_UNIX03 #if CPU(X86) return reinterpret_cast<void*>(regs.__esp); #elif CPU(X86_64) return reinterpret_cast<void*>(regs.__rsp); #elif CPU(PPC) || CPU(PPC64) return reinterpret_cast<void*>(regs.__r1); #elif CPU(ARM) return reinterpret_cast<void*>(regs.__sp); #else #error Unknown Architecture #endif #else // !__DARWIN_UNIX03 #if CPU(X86) return reinterpret_cast<void*>(regs.esp); #elif CPU(X86_64) return reinterpret_cast<void*>(regs.rsp); #elif CPU(PPC) || CPU(PPC64) return reinterpret_cast<void*>(regs.r1); #else #error Unknown Architecture #endif #endif // __DARWIN_UNIX03 // end OS(DARWIN) #elif CPU(X86) && OS(WINDOWS) return reinterpret_cast<void*>((uintptr_t) regs.Esp); #elif CPU(X86_64) && OS(WINDOWS) return reinterpret_cast<void*>((uintptr_t) regs.Rsp); #elif USE(PTHREADS) void* stackBase = 0; size_t stackSize = 0; int rc = pthread_attr_getstack(®s, &stackBase, &stackSize); (void)rc; // FIXME: Deal with error code somehow? Seems fatal. ASSERT(stackBase); return static_cast<char*>(stackBase) + stackSize; #else #error Need a way to get the stack pointer for another thread on this platform #endif }
void mono_threads_core_get_stack_bounds (guint8 **staddr, size_t *stsize) { pthread_attr_t attr; guint8 *current = (guint8*)&attr; *staddr = NULL; *stsize = (size_t)-1; pthread_getattr_np (pthread_self (), &attr); pthread_attr_getstack (&attr, (void**)staddr, stsize); pthread_attr_destroy (&attr); if (*staddr && ((current <= *staddr) || (current > *staddr + *stsize))) slow_get_thread_bounds (current, staddr, stsize); }
int main() { pthread_attr_t attr; int rc; /* Initialize attr */ rc = pthread_attr_init(&attr); if( rc != 0) { perror(ERROR_PREFIX "pthread_attr_init"); exit(PTS_UNRESOLVED); } /* Get the default stack_addr and stack_size value */ rc = pthread_attr_getstack(&attr, &stack_addr, &stack_size); if( rc != 0) { perror(ERROR_PREFIX "pthread_attr_getstack"); exit(PTS_UNRESOLVED); } /* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size); */ stack_size = STACKSIZE; if (posix_memalign (&stack_addr, sysconf(_SC_PAGE_SIZE), stack_size) != 0) { perror (ERROR_PREFIX "out of memory while " "allocating the stack memory"); exit(PTS_UNRESOLVED); } /* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size); */ rc = pthread_attr_setstack(&attr, stack_addr, stack_size); if (rc != EINVAL ) { perror(ERROR_PREFIX "Got the wrong return value"); exit(PTS_FAIL); } rc = pthread_attr_destroy(&attr); if(rc != 0) { perror(ERROR_PREFIX "pthread_attr_destroy"); exit(PTS_UNRESOLVED); } printf("Test PASSED\n"); return PTS_PASS; }
static int get_stack_attr(void *low, void *high) { /* GNU Pthread specific */ pthread_attr_t attr; uintptr_t stackaddr; size_t stacksize; if (pthread_getattr_np(pthread_self(), &attr)) { return 1; } if (pthread_attr_getstack(&attr, (void *)&stackaddr, &stacksize)) { return 1; } *(uintptr_t *)low = stackaddr; *(uintptr_t *)high = stackaddr + stacksize; return 0; }
void * GetNativeStackBaseImpl() { pthread_t thread = pthread_self(); # if defined(XP_MACOSX) || defined(DARWIN) return pthread_get_stackaddr_np(thread); # else pthread_attr_t sattr; pthread_attr_init(&sattr); # if defined(__OpenBSD__) stack_t ss; # elif defined(PTHREAD_NP_H) || defined(_PTHREAD_NP_H_) || defined(NETBSD) /* e.g. on FreeBSD 4.8 or newer, [email protected] */ pthread_attr_get_np(thread, &sattr); # else /* * FIXME: this function is non-portable; * other POSIX systems may have different np alternatives */ pthread_getattr_np(thread, &sattr); # endif void *stackBase = 0; size_t stackSize = 0; # ifdef DEBUG int rc = # endif # if defined(__OpenBSD__) pthread_stackseg_np(pthread_self(), &ss); stackBase = (void*)((size_t) ss.ss_sp - ss.ss_size); stackSize = ss.ss_size; # else pthread_attr_getstack(&sattr, &stackBase, &stackSize); # endif JS_ASSERT(!rc); JS_ASSERT(stackBase); pthread_attr_destroy(&sattr); # if JS_STACK_GROWTH_DIRECTION > 0 return stackBase; # else return static_cast<char*>(stackBase) + stackSize; # endif # endif }
/* naming : pthread_create = start */ int mas_ticker_start( const mas_options_t * popts ) { CTRL_PREPARE; /* EVAL_PREPARE; */ int r = 0; MFP( "\x1b]2;starting ticker; mode:%d\x7", ctrl.ticker_mode ); if ( !ctrl.threads.n.ticker.thread ) { { ( void ) /* r = */ pthread_attr_getstack( &ctrl.thglob.ticker_attr, &ticker_stackaddr, &ticker_stacksize ); tMSG( "creating ticker thread stack:%lu @ %p", ( unsigned long ) ticker_stacksize, ticker_stackaddr ); HMSG( "+ TICKER mode %d", ctrl.ticker_mode ); } /* if ( !tmp ) */ /* tmp = mas_malloc( 4321 ); */ MAS_LOG( "starting ticker th." ); /* r = mas_xpthread_create( &ctrl.threads.n.ticker.thread, mas_ticker_th, MAS_THREAD_TICKER, NULL ); */ r = pthread_create( &ctrl.threads.n.ticker.thread, &ctrl.thglob.ticker_attr, mas_ticker_th, NULL ); #ifdef SCHED_IDLE { int policy, rs; struct sched_param sched; rs = pthread_getschedparam( ctrl.threads.n.ticker.thread, &policy, &sched ); /* SCHED_IDLE ... SCHED_RR */ rs = pthread_setschedparam( ctrl.threads.n.ticker.thread, SCHED_IDLE, &sched ); /* rs = pthread_getschedparam( ctrl.threads.n.ticker.thread, &policy, &sched ); */ MAS_LOG( "(%d) created(?) ticker thread [%lx] %d - %d (%d)", r, ctrl.threads.n.ticker.thread, policy, sched.sched_priority, rs ); tMSG( "(%d) created(?) ticker thread [%lx] %d - %d (%d)", r, ctrl.threads.n.ticker.thread, policy, sched.sched_priority, rs ); } #else MAS_LOG( "(%d) created(?) ticker thread [%lx]", r, ctrl.threads.n.ticker.thread ); #endif } else { MAS_LOG( "running w/o ticker th." ); } return r; }
int main(void) { pthread_t tid; pthread_attr_t attr; void *stack_addr; int stack_size; int ret; while (1) { stack_addr = malloc(PAGE_SIZE * 8); // 1. 指针不能位运算,因此转换成unsigned long // 2. & 0x7 检查地址是否对齐: 32位系统,2^12 >> 0x1000 if ((unsigned long)stack_addr & 0x7 != 0) { printf("地址不是对齐的\n"); free(stack_addr); } else break; } printf("stack_addr: %p\n", stack_addr); pthread_attr_init(&attr); pthread_attr_setstack(&attr, stack_addr, PAGE_SIZE * 8); pthread_attr_getstack(&attr, &stack_addr, &stack_size); printf("stack_addr: %p, stack_size: %#x\n", stack_addr, stack_size); pthread_create(&tid, &attr, thr_rtn, NULL); ret = pthread_join(tid, NULL); if (ret != 0) { printf("thread has detached\n"); perror("pthread_join"); } free(stack_addr); pthread_attr_destroy(&attr); return 0; }
void Thread::_poison_stack() { pthread_attr_t attr; size_t stack_size, guard_size; void *stackp; uint8_t *end, *start, *curr; uint32_t *p; if (pthread_getattr_np(_ctx, &attr) != 0 || pthread_attr_getstack(&attr, &stackp, &stack_size) != 0 || pthread_attr_getguardsize(&attr, &guard_size) != 0) { return; } /* The stack either grows upward or downard. The guard part always * protects the end */ end = (uint8_t *) stackp; start = end + stack_size; curr = (uint8_t *) alloca(sizeof(uint32_t)); /* if curr is closer to @end, the stack actually grows from low to high * virtual address: this is because this function should be executing very * early in the thread's life and close to the thread creation, assuming * the actual stack size is greater than the guard size and the stack * until now is resonably small */ if (abs(curr - start) > abs(curr - end)) { std::swap(end, start); end -= guard_size; for (p = (uint32_t *) end; p > (uint32_t *) curr; p--) { *p = STACK_POISON; } } else { end += guard_size; for (p = (uint32_t *) end; p < (uint32_t *) curr; p++) { *p = STACK_POISON; } } _stack_debug.start = (uint32_t *) start; _stack_debug.end = (uint32_t *) end; }
static void * tf (void *a) { int result = 0; puts ("child start"); pthread_attr_t attr; if (pthread_getattr_np (pthread_self (), &attr) != 0) { puts ("getattr_np failed"); exit (1); } size_t test_size; void *test_stack; if (pthread_attr_getstack (&attr, &test_stack, &test_size) != 0) { puts ("attr_getstack failed"); exit (1); } if (test_size != size) { printf ("child: reported size differs: is %zu, expected %zu\n", test_size, size); result = 1; } if (test_stack != stack) { printf ("child: reported stack address differs: is %p, expected %p\n", test_stack, stack); result = 1; } puts ("child OK"); return result ? (void *) 1l : NULL; }
static void display_stack_related_attributes(pthread_attr_t *attr, char *prefix) { int s; size_t stack_size, guard_size; void *stack_addr; s = pthread_attr_getguardsize(attr, &guard_size); if (s != 0) handle_error_en(s, "pthread_attr_getguardsize"); printf("%sGuard size = %lu bytes\n", prefix, guard_size); s = pthread_attr_getstack(attr, &stack_addr, &stack_size); if (s != 0) handle_error_en(s, "pthread_attr_getstack"); printf("%sStack address = %p", prefix, stack_addr); if (stack_size > 0) printf(" (EOS = %p)", (char *) stack_addr + stack_size); printf("\n"); printf("%sStack size = 0x%lx (%lu) bytes\n", prefix, stack_size, stack_size); }
//static void XLinuxTask_preemptive::GetStack(void** outStackAddr, size_t* outStackSize) { pthread_attr_t attr; pthread_attr_init(&attr); int res = pthread_getattr_np(pthread_self(), &attr); xbox_assert(res==0); void* stackAddr = NULL; size_t stackSize = 0; res = pthread_attr_getstack(&attr, &stackAddr, &stackSize); xbox_assert(res == 0); if (outStackAddr) *outStackAddr = stackAddr; if (outStackSize) *outStackSize = stackSize; pthread_attr_destroy(&attr); }
void *AsyncFuncImpl::ThreadFunc(void *obj) { pthread_attr_t *attr; size_t stacksize, guardsize; void *stackaddr; attr = ((AsyncFuncImpl*)obj)->getThreadAttr(); pthread_attr_getstack(attr, &stackaddr, &stacksize); // Get the guard page's size, because the stack address returned // above starts at the guard page, so the thread's stack limit is // stackaddr + guardsize. if (pthread_attr_getguardsize(attr, &guardsize) != 0) guardsize = 0; ASSERT(stackaddr != NULL); ASSERT(stacksize >= PTHREAD_STACK_MIN); Util::s_stackLimit = uintptr_t(stackaddr) + guardsize; Util::s_stackSize = stacksize; ((AsyncFuncImpl*)obj)->threadFuncImpl(); return NULL; }
static int get_self_pthread_attr (const char *id, void **stackaddr, size_t *stacksize) { pthread_attr_t attr; int ret; pthread_t me = pthread_self (); if ((ret = pthread_getattr_np (me, &attr)) < 0) { printf ("%s: pthread_getattr_np failed: %s\n", id, strerror (ret)); return 1; } if ((ret = pthread_attr_getstack (&attr, stackaddr, stacksize)) < 0) { printf ("%s: pthread_attr_getstack returned error: %s\n", id, strerror (ret)); return 1; } return 0; }
StackLocator::StackLocator() { pthread_t self = pthread_self(); pthread_attr_t selfAttrs; invariant(pthread_attr_init(&selfAttrs) == 0); invariant(pthread_getattr_np(self, &selfAttrs) == 0); ON_BLOCK_EXIT(pthread_attr_destroy, &selfAttrs); void* base = nullptr; size_t size = 0; auto result = pthread_attr_getstack(&selfAttrs, &base, &size); invariant(result == 0); invariant(base != nullptr); invariant(size != 0); // TODO: Assumes a downward growing stack. Note here that // getstack returns the stack *base*, being the bottom of the // stack, so we need to add size to it. _end = base; _begin = static_cast<char*>(_end) + size; }
void StackBounds::initialize() { void* stackBase = 0; size_t stackSize = 0; pthread_t thread = pthread_self(); pthread_attr_t sattr; pthread_attr_init(&sattr); #if HAVE(PTHREAD_NP_H) || OS(NETBSD) // e.g. on FreeBSD 5.4, [email protected] pthread_attr_get_np(thread, &sattr); #else // FIXME: this function is non-portable; other POSIX systems may have different np alternatives pthread_getattr_np(thread, &sattr); #endif int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize); (void)rc; // FIXME: Deal with error code somehow? Seems fatal. ASSERT(stackBase); pthread_attr_destroy(&sattr); m_bound = stackBase; m_origin = static_cast<char*>(stackBase) + stackSize; }
static int print_thread_attr(pthread_attr_t *attr) { if (attr == NULL) { return THREAD_ATTR_FAILED; } int detach_state = 0; int ret = 0; char *stack_addr = NULL; size_t stack_size = 0; size_t guard_size = 0; ret = pthread_attr_getdetachstate(attr, &detach_state); if (detach_state == PTHREAD_CREATE_JOINABLE) { printf("Thread detach state: JOINABLE\n"); } else if (detach_state == PTHREAD_CREATE_DETACHED) { printf("Thread detach state: DETACHED\n"); } ret = pthread_attr_getstack(attr, (void**)&stack_addr, &stack_size); printf("stack_addr:%p, stack_size:%zd\n", stack_addr, stack_size); ret = pthread_attr_getstacksize(attr, &stack_size); printf("stack size:%#x\n", stack_size); ret = pthread_attr_getguardsize(attr, &guard_size); printf("guard size:%#x\n", guard_size); ret = pthread_getconcurrency(); printf("concurrency is %d\n", ret); return THREAD_ATTR_OK; }
void *thread_func() { pthread_attr_t attr; void *saddr; size_t ssize; int rc; if ((rc = pthread_getattr_np(pthread_self(), &attr)) != 0) { printf(ERROR_PREFIX "pthread_getattr_np: %s", strerror(rc)); pthread_exit((void *)PTS_UNRESOLVED); } if ((rc = pthread_attr_getstack(&attr, &saddr, &ssize)) != 0) { printf(ERROR_PREFIX "pthread_attr_getstack: %s", strerror(rc)); pthread_exit((void *)PTS_UNRESOLVED); } if (ssize != stack_size || saddr != stack_addr) { printf(ERROR_PREFIX "got the wrong stacksize or stackaddr"); pthread_exit((void *)PTS_FAIL); } pthread_exit(NULL); return NULL; }
/** * Determines the stack address of the current thread */ static void* getStackAddress(void) { void* result = NULL; size_t stackSize = 0; pthread_t self = pthread_self(); #if defined(DARWIN) result = pthread_get_stackaddr_np(self); stackSize = pthread_get_stacksize_np(self); // pthread_get_stackaddr_np returns the beginning (highest address) of the stack // while we want the address of the memory area allocated for the stack (lowest address). result -= stackSize; #else size_t guardSize = 0; pthread_attr_t attr; pthread_getattr_np(self, &attr); pthread_attr_getstack(&attr, &result, &stackSize); pthread_attr_getguardsize(&attr, &guardSize); // On Linux pthread_attr_getstack() returns the address of the memory area allocated for the stack // including the guard page (except for the main thread which returns the correct stack address and // pthread_attr_getguardsize() returns 0 even if there is a guard page). result += guardSize; #endif return result; }
inline int find_stack_addr_size(void** paddr, size_t* psize) { #if defined (HAIKU) int status; thread_info info; thread_id this_thread = find_thread(NULL); status = get_thread_info(this_thread,&info); *paddr = info.stack_base; *psize = (size_t)info.stack_base - (size_t)info.stack_end; return 0; #else int err; pthread_attr_t pthread_attr; void* stack_addr; size_t stack_size; pthread_t thread = pthread_self(); if (!paddr) return EINVAL; err = pthread_attr_init(&pthread_attr); if (err != 0) return err; #if defined(FREEBSD) err = pthread_attr_get_np(thread, &pthread_attr); #else err = pthread_getattr_np(thread, &pthread_attr); #endif if (err != 0) return err; err = pthread_attr_getstack(&pthread_attr, &stack_addr, &stack_size); if (err != 0) return err; pthread_attr_destroy(&pthread_attr); *paddr = (void*)((size_t)stack_addr + stack_size); *psize = stack_size; return 0; #endif }
static void display_stack_attr (pthread_attr_t *attr, char *prefix) { int s; size_t stack_size, guard_size, stack_size_check; void *stack_addr; s = pthread_attr_getguardsize(attr, &guard_size); if (s != 0) handle_error_en(s, "pthread_attr_getguardsize"); printf("%sGuard size = %d bytes\n", prefix, guard_size); s = pthread_attr_getstack(attr, &stack_addr, &stack_size); if (s != 0) handle_error_en(s, "pthread_attr_getstack"); printf("%sStack address = %p", prefix, stack_addr); if (stack_size > 0) printf(" (EOS = %p)", (char *) stack_addr + stack_size); printf("\n"); s = pthread_attr_getstacksize (attr, &stack_size_check); if (s != 0) handle_error_en(s, "pthread_attr_getstacksize"); assert (stack_size_check == stack_size); printf("%sStack size = 0x%x (%d) bytes\n", prefix, stack_size, stack_size); }
void attach_os_thread(init_thread_data *scribble) { os_thread_t os = pthread_self(); odxprint(misc, "attach_os_thread: attaching to %p", os); struct thread *th = create_thread_struct(NIL); block_deferrable_signals(&scribble->oldset); th->no_tls_value_marker = NO_TLS_VALUE_MARKER_WIDETAG; /* We don't actually want a pthread_attr here, but rather than add * `if's to the post-mostem, let's just keep that code happy by * keeping it initialized: */ pthread_attr_init(th->os_attr); #ifndef LISP_FEATURE_WIN32 /* On windows, arch_os_thread_init will take care of finding the * stack. */ void *stack_addr; size_t stack_size; #ifdef LISP_FEATURE_OPENBSD stack_t stack; pthread_stackseg_np(os, &stack); stack_size = stack.ss_size; stack_addr = (void*)((size_t)stack.ss_sp - stack_size); #elif defined LISP_FEATURE_SUNOS stack_t stack; thr_stksegment(&stack); stack_size = stack.ss_size; stack_addr = (void*)((size_t)stack.ss_sp - stack_size); #elif defined(LISP_FEATURE_DARWIN) stack_addr = pthread_get_stackaddr_np(os); stack_size = pthread_get_stacksize_np(os); #else pthread_attr_t attr; #ifdef LISP_FEATURE_FREEBSD pthread_attr_get_np(os, &attr); #else int pthread_getattr_np(pthread_t, pthread_attr_t *); pthread_getattr_np(os, &attr); #endif pthread_attr_getstack(&attr, &stack_addr, &stack_size); #endif th->control_stack_start = stack_addr; th->control_stack_end = (void *) (((uintptr_t) stack_addr) + stack_size); #endif init_new_thread(th, scribble, 0); /* We will be calling into Lisp soon, and the functions being called * recklessly ignore the comment in target-thread which says that we * must be careful to not cause GC while initializing a new thread. * Since we first need to create a fresh thread object, it's really * tempting to just perform such unsafe allocation though. So let's * at least try to suppress GC before consing, and hope that it * works: */ bind_variable(GC_INHIBIT, T, th); uword_t stacksize = (uword_t) th->control_stack_end - (uword_t) th->control_stack_start; odxprint(misc, "attach_os_thread: attached %p as %p (0x%lx bytes stack)", os, th, (long) stacksize); }
int main() { pthread_t new_th; pthread_attr_t attr; size_t ssize; void *saddr; int rc; /* Initialize attr */ rc = pthread_attr_init(&attr); if (rc != 0) { printf(ERROR_PREFIX "pthread_attr_init: %s", strerror(rc)); exit(PTS_UNRESOLVED); } /* Get the default stack_addr and stack_size value */ rc = pthread_attr_getstack(&attr, &stack_addr, &stack_size); if (rc != 0) { printf(ERROR_PREFIX "pthread_attr_getstack", strerror(rc)); exit(PTS_UNRESOLVED); } /* * Use smallest usable stack size for us to be able to call * printf(3) / pthread_exit(3) without segfaulting. * * If for whatever reason PTHREAD_STACK_MIN is set to 0 (which it can * be according to POSIX), posix_memalign will fail with EINVAL. */ stack_size = PTHREAD_STACK_MIN * 4; if ((rc = posix_memalign(&stack_addr, sysconf(_SC_PAGE_SIZE), stack_size)) != 0) { printf(ERROR_PREFIX "posix_memalign: %s\n", strerror(rc)); exit(PTS_UNRESOLVED); } if ((rc = pthread_attr_setstack(&attr, stack_addr, stack_size)) != 0) { printf(ERROR_PREFIX "pthread_attr_setstack: %s\n", strerror(rc)); exit(PTS_UNRESOLVED); } if ((rc = pthread_attr_getstack(&attr, &saddr, &ssize)) != 0) { printf(ERROR_PREFIX "pthread_attr_getstack: %s\n", strerror(rc)); exit(PTS_UNRESOLVED); } if ((rc = pthread_create(&new_th, &attr, thread_func, NULL)) != 0) { printf(ERROR_PREFIX "pthread_create: %s\n", strerror(rc)); exit(PTS_FAIL); } if ((rc = pthread_join(new_th, NULL)) != 0) { printf(ERROR_PREFIX "pthread_join: %s\n", strerror(rc)); exit(PTS_UNRESOLVED); } if ((rc = pthread_attr_destroy(&attr)) != 0) { printf(ERROR_PREFIX "pthread_attr_destroy: %s\n", strerror(rc)); exit(PTS_UNRESOLVED); } printf("Test PASSED\n"); return PTS_PASS; }
int main() { pthread_t new_th; pthread_attr_t attr; size_t ssize; void *saddr; int rc; /* Initialize attr */ rc = pthread_attr_init(&attr); if (rc != 0) { perror(ERROR_PREFIX "pthread_attr_init"); exit(PTS_UNRESOLVED); } /* Get the default stack_addr and stack_size value */ rc = pthread_attr_getstack(&attr, &stack_addr, &stack_size); if (rc != 0) { perror(ERROR_PREFIX "pthread_attr_getstack"); exit(PTS_UNRESOLVED); } /* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size); */ stack_size = PTHREAD_STACK_MIN; if (posix_memalign (&stack_addr, sysconf(_SC_PAGE_SIZE), stack_size) != 0) { perror (ERROR_PREFIX "out of memory while " "allocating the stack memory"); exit(PTS_UNRESOLVED); } /* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size);*/ rc = pthread_attr_setstack(&attr, stack_addr, stack_size); if (rc != 0) { perror(ERROR_PREFIX "pthread_attr_setstack"); exit(PTS_UNRESOLVED); } rc = pthread_attr_getstack(&attr, &saddr, &ssize); if (rc != 0) { perror(ERROR_PREFIX "pthread_attr_getstack"); exit(PTS_UNRESOLVED); } /* printf("saddr = %p, ssize = %u\n", saddr, ssize); */ rc = pthread_create(&new_th, &attr, thread_func, NULL); if (rc !=0) { perror(ERROR_PREFIX "failed to create a thread"); exit(PTS_FAIL); } rc = pthread_join(new_th, NULL); if (rc != 0) { perror(ERROR_PREFIX "pthread_join"); exit(PTS_UNRESOLVED); } rc = pthread_attr_destroy(&attr); if (rc != 0) { perror(ERROR_PREFIX "pthread_attr_destroy"); exit(PTS_UNRESOLVED); } printf("Test PASSED\n"); return PTS_PASS; }