Author: bonefish Date: 2011-05-29 15:44:14 +0200 (Sun, 29 May 2011) New Revision: 41808 Changeset: https://dev.haiku-os.org/changeset/41808 Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread.h haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp Log: * ThreadCreationAttributes: Added attribute additional_stack_size, which allows to allocate additional space on the thread stack. * thread_create_thread(): Added handling for creating the user stack of a main thread. Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/private/kernel/thread.h 2011-05-29 13:09:34 UTC (rev 41807) +++ haiku/branches/developer/bonefish/signals/headers/private/kernel/thread.h 2011-05-29 13:44:14 UTC (rev 41808) @@ -39,6 +39,9 @@ team_id team; Thread* thread; sigset_t signal_mask; + size_t additional_stack_size; // additional space in the stack area + // after the TLS region, not used as + // thread stack public: ThreadCreationAttributes() {} Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp 2011-05-29 13:09:34 UTC (rev 41807) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp 2011-05-29 13:44:14 UTC (rev 41808) @@ -504,6 +504,7 @@ this->team = team >= 0 ? team : team_get_kernel_team()->id; this->thread = thread; this->signal_mask = 0; + this->additional_stack_size = 0; } @@ -547,6 +548,7 @@ thread = NULL; signal_mask = currentThread->sig_block_mask; // inherit the current thread's signal mask + additional_stack_size = 0; return B_OK; } @@ -780,10 +782,11 @@ if (stackBase == NULL) { // no user-defined stack -- allocate one - stackBase = (uint8*)(addr_t)USER_STACK_REGION; if (stackSize == 0) { - stackSize = USER_STACK_SIZE; + // Use the default size (a different one for a main thread). + stackSize = thread->id == team->id + ? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE; } else { // Verify that the given stack size is large enough. if (stackSize < MIN_USER_STACK_SIZE - TLS_SIZE) @@ -793,16 +796,32 @@ } stackSize += USER_STACK_GUARD_PAGES * B_PAGE_SIZE; + size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + + attributes.additional_stack_size); + snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%ld_stack", attributes.name, thread->id); + virtual_address_restrictions virtualRestrictions = {}; + if (thread->id == team->id) { + // The main thread gets a fixed position at the top of the stack + // address range. + stackBase = (uint8*)(USER_STACK_REGION + USER_STACK_REGION_SIZE + - areaSize); + virtualRestrictions.address_specification = B_BASE_ADDRESS; + + } else { + // not a main thread + stackBase = (uint8*)(addr_t)USER_STACK_REGION; + virtualRestrictions.address_specification = B_BASE_ADDRESS; + } virtualRestrictions.address = (void*)stackBase; - virtualRestrictions.address_specification = B_BASE_ADDRESS; + physical_address_restrictions physicalRestrictions = {}; + stackArea = create_area_etc(team->id, stack_name, - stackSize + TLS_SIZE, B_NO_LOCK, - B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, 0, - &virtualRestrictions, &physicalRestrictions, + areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, + 0, &virtualRestrictions, &physicalRestrictions, (void**)&stackBase); if (stackArea < 0) return stackArea;