Ticket #8233: 0001-Add-support-for-pthread_attr_-get-set-guardsize.patch

File 0001-Add-support-for-pthread_attr_-get-set-guardsize.patch, 28.3 KB (added by hamish, 12 years ago)
  • headers/posix/pthread.h

    From a1e6675fcbb598b8df358b87c85c7047a491a994 Mon Sep 17 00:00:00 2001
    From: Hamish Morrison <hamish@lavabit.com>
    Date: Wed, 15 Feb 2012 13:48:12 +0000
    Subject: [PATCH] Add support for pthread_attr_(get/set)guardsize()
    
    Adds pthread_attr_(get/set)guardsize() functions, adds a guardPages
    parameter to create_area_etc() to support this, and updates all usages
    of create_area_etc().
    ---
     headers/posix/pthread.h                            |    9 ++--
     headers/private/kernel/vm/vm.h                     |    2 +
     headers/private/libroot/pthread_private.h          |    1 +
     headers/private/system/thread_defs.h               |   14 +++----
     .../kernel/bus_managers/scsi/dma_buffer.cpp        |    2 +-
     src/add-ons/kernel/bus_managers/scsi/emulation.cpp |    2 +-
     src/libs/compat/freebsd_network/compat_cpp.cpp     |    2 +-
     .../arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp |    2 +-
     src/system/kernel/arch/x86/arch_cpu.cpp            |    2 +-
     src/system/kernel/arch/x86/arch_int.cpp            |    2 +-
     .../arch/x86/paging/32bit/X86PagingMethod32Bit.cpp |    2 +-
     .../arch/x86/paging/pae/X86PagingMethodPAE.cpp     |    2 +-
     src/system/kernel/arch/x86/vm86.cpp                |    2 +-
     src/system/kernel/debug/debug_heap.cpp             |    2 +-
     src/system/kernel/debug/tracing.cpp                |    8 ++--
     src/system/kernel/device_manager/dma_resources.cpp |    2 +-
     src/system/kernel/elf.cpp                          |    2 +-
     src/system/kernel/sem.cpp                          |    2 +-
     src/system/kernel/slab/MemoryManager.cpp           |    2 +-
     src/system/kernel/team.cpp                         |    2 +-
     src/system/kernel/thread.cpp                       |   44 +++++++++++--------
     src/system/kernel/vm/vm.cpp                        |   27 +++++-------
     src/system/libroot/posix/pthread/pthread.cpp       |    4 +-
     src/system/libroot/posix/pthread/pthread_attr.c    |   28 ++++++++++++
     24 files changed, 100 insertions(+), 67 deletions(-)
    
    diff --git a/headers/posix/pthread.h b/headers/posix/pthread.h
    index cc5b900..ac84d62 100644
    a b extern int pthread_attr_getschedparam(const pthread_attr_t *attr,  
    185185extern int pthread_attr_setschedparam(pthread_attr_t *attr,
    186186    const struct sched_param *param);
    187187
     188extern int pthread_attr_getguardsize(const pthread_attr_t *attr,
     189    size_t *guardsize);
     190extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
     191
    188192#if 0   /* Unimplemented attribute functions: */
    189193
    190194/* [TPS] */
    extern int pthread_attr_getschedpolicy(const pthread_attr_t *attr,  
    196200    int *policy);
    197201extern int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
    198202
    199 /* [XSI] */
    200 extern int pthread_attr_getguardsize(const pthread_attr_t *attr,
    201     size_t *guardsize);
    202 extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
    203 
    204203/* [TSA] */
    205204extern int pthread_attr_getstackaddr(const pthread_attr_t *attr,
    206205    void **stackaddr);
  • headers/private/kernel/vm/vm.h

    diff --git a/headers/private/kernel/vm/vm.h b/headers/private/kernel/vm/vm.h
    index 9163e3b..794766e 100644
    a b void forbid_page_faults(void);  
    7878// private kernel only extension (should be moved somewhere else):
    7979area_id create_area_etc(team_id team, const char *name, uint32 size,
    8080            uint32 lock, uint32 protection, uint32 flags,
     81            page_num_t guardPages,
    8182            const virtual_address_restrictions* virtualAddressRestrictions,
    8283            const physical_address_restrictions* physicalAddressRestrictions,
    8384            void **_address);
    status_t vm_reserve_address_range(team_id team, void **_address,  
    9697            uint32 addressSpec, addr_t size, uint32 flags);
    9798area_id vm_create_anonymous_area(team_id team, const char* name, addr_t size,
    9899            uint32 wiring, uint32 protection, uint32 flags,
     100            page_num_t guardPages,
    99101            const virtual_address_restrictions* virtualAddressRestrictions,
    100102            const physical_address_restrictions* physicalAddressRestrictions,
    101103            bool kernel, void** _address);
  • headers/private/libroot/pthread_private.h

    diff --git a/headers/private/libroot/pthread_private.h b/headers/private/libroot/pthread_private.h
    index f50bd28..1ddc00c 100644
    a b typedef struct _pthread_attr {  
    4040    int32       detach_state;
    4141    int32       sched_priority;
    4242    size_t      stack_size;
     43    size_t      guard_size;
    4344} pthread_attr;
    4445
    4546typedef struct _pthread_rwlockattr {
  • headers/private/system/thread_defs.h

    diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h
    index 9f1b527..5153ec7 100644
    a b  
    1212
    1313
    1414/** Size of the stack given to teams in user space */
    15 #define USER_STACK_GUARD_PAGES      4                               // 16 kB
    16 #define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024 \
    17                         - USER_STACK_GUARD_PAGES * B_PAGE_SIZE)     // 16 MB
    18 #define USER_STACK_SIZE             (256 * 1024 \
    19                         - USER_STACK_GUARD_PAGES * B_PAGE_SIZE)     // 256 kB
    20 #define MIN_USER_STACK_SIZE         (4 * 1024)                      // 4 KB
    21 #define MAX_USER_STACK_SIZE         (16 * 1024 * 1024 \
    22                         - USER_STACK_GUARD_PAGES * B_PAGE_SIZE)     // 16 MB
     15#define USER_STACK_GUARD_PAGES      4                       // 16 kB
     16#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024)      // 16 MB
     17#define USER_STACK_SIZE             (256 * 1024)            // 256 kB
     18#define MIN_USER_STACK_SIZE         (4 * 1024)              // 4 KB
     19#define MAX_USER_STACK_SIZE         (16 * 1024 * 1024)      // 16 MB
    2320
    2421
    2522// The type of object a thread blocks on (thread::wait::type, set by
    struct thread_creation_attributes {  
    5047    void*       args2;
    5148    void*       stack_address;
    5249    size_t      stack_size;
     50    size_t      guard_size;
    5351    pthread_t   pthread;
    5452    uint32      flags;
    5553};
  • src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp

    diff --git a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp
    index 9da56a5..1b32a1d 100644
    a b scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)  
    195195            // TODO: Use 64 bit addresses, if possible!
    196196#endif
    197197        buffer->area = create_area_etc(B_SYSTEM_TEAM, "DMA buffer", size,
    198             B_CONTIGUOUS, 0, 0, &virtualRestrictions, &physicalRestrictions,
     198            B_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, &physicalRestrictions,
    199199            (void**)&buffer->address);
    200200
    201201        if (buffer->area < 0) {
  • src/add-ons/kernel/bus_managers/scsi/emulation.cpp

    diff --git a/src/add-ons/kernel/bus_managers/scsi/emulation.cpp b/src/add-ons/kernel/bus_managers/scsi/emulation.cpp
    index 9127e24..161b273 100644
    a b scsi_init_emulation_buffer(scsi_device_info *device, size_t buffer_size)  
    7474    physical_address_restrictions physicalRestrictions = {};
    7575    physicalRestrictions.alignment = buffer_size;
    7676    device->buffer_area = create_area_etc(B_SYSTEM_TEAM, "ATAPI buffer",
    77         total_size, B_32_BIT_CONTIGUOUS, 0, 0, &virtualRestrictions,
     77        total_size, B_32_BIT_CONTIGUOUS, 0, 0, 0, &virtualRestrictions,
    7878        &physicalRestrictions, &address);
    7979        // TODO: Use B_CONTIGUOUS, if possible!
    8080
  • src/libs/compat/freebsd_network/compat_cpp.cpp

    diff --git a/src/libs/compat/freebsd_network/compat_cpp.cpp b/src/libs/compat/freebsd_network/compat_cpp.cpp
    index 97c9243..a9ae740 100644
    a b _kernel_contigmalloc_cpp(const char* file, int line, size_t size,  
    3737
    3838    void* address;
    3939    area_id area = create_area_etc(B_SYSTEM_TEAM, name, size, B_CONTIGUOUS,
    40         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags,
     40        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, 0,
    4141        &virtualRestrictions, &physicalRestrictions, &address);
    4242    if (area < 0)
    4343        return NULL;
  • src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp

    diff --git a/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp b/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp
    index 9214286..b2d218f 100644
    a b ARMPagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(  
    197197    physical_address_restrictions physicalRestrictions = {};
    198198    area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
    199199        PAGE_ALIGN(areaSize), B_FULL_LOCK,
    200         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     200        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    201201        &virtualRestrictions, &physicalRestrictions, &data);
    202202    if (dataArea < 0)
    203203        return dataArea;
  • src/system/kernel/arch/x86/arch_cpu.cpp

    diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp
    index 035c352..2be5bd2 100644
    a b arch_cpu_init_post_vm(kernel_args *args)  
    753753    physical_address_restrictions physicalRestrictions = {};
    754754    create_area_etc(B_SYSTEM_TEAM, "double fault stacks",
    755755        kDoubleFaultStackSize * smp_get_num_cpus(), B_FULL_LOCK,
    756         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     756        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    757757        &virtualRestrictions, &physicalRestrictions,
    758758        (void**)&sDoubleFaultStacks);
    759759
  • src/system/kernel/arch/x86/arch_int.cpp

    diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp
    index 123f575..a0dc35b 100644
    a b arch_int_init_post_vm(struct kernel_args *args)  
    873873        virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS;
    874874        physical_address_restrictions physicalRestrictions = {};
    875875        area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS,
    876             B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     876            B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    877877            &virtualRestrictions, &physicalRestrictions, (void**)&idt);
    878878        if (area < 0)
    879879            return area;
  • src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp

    diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp
    index 9f84057..58cab87 100644
    a b X86PagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(  
    195195    physical_address_restrictions physicalRestrictions = {};
    196196    area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
    197197        PAGE_ALIGN(areaSize), B_FULL_LOCK,
    198         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     198        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    199199        &virtualRestrictions, &physicalRestrictions, &data);
    200200    if (dataArea < 0)
    201201        return dataArea;
  • src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp

    diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp
    index e7001bb..5136e77 100644
    a b X86PagingMethodPAE::PhysicalPageSlotPool::AllocatePool(  
    486486    physical_address_restrictions physicalRestrictions = {};
    487487    area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
    488488        PAGE_ALIGN(areaSize), B_FULL_LOCK,
    489         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     489        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    490490        &virtualRestrictions, &physicalRestrictions, &data);
    491491    if (dataArea < 0)
    492492        return dataArea;
  • src/system/kernel/arch/x86/vm86.cpp

    diff --git a/src/system/kernel/arch/x86/vm86.cpp b/src/system/kernel/arch/x86/vm86.cpp
    index ebfce51..39adf38 100644
    a b vm86_prepare(struct vm86_state *state, unsigned int ramSize)  
    552552    virtualRestrictions.address_specification = B_EXACT_ADDRESS;
    553553    physical_address_restrictions physicalRestrictions = {};
    554554    state->ram_area = create_area_etc(team->id, "dos", ramSize, B_NO_LOCK,
    555         B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
     555        B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
    556556        &physicalRestrictions, &address);
    557557    if (state->ram_area < B_OK) {
    558558        ret = state->ram_area;
  • src/system/kernel/debug/debug_heap.cpp

    diff --git a/src/system/kernel/debug/debug_heap.cpp b/src/system/kernel/debug/debug_heap.cpp
    index 069e97d..326d865 100644
    a b debug_heap_init()  
    296296    physical_address_restrictions physicalRestrictions = {};
    297297    area_id area = create_area_etc(B_SYSTEM_TEAM, "kdebug heap", KDEBUG_HEAP,
    298298        B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    299         CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions,
     299        CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, &physicalRestrictions,
    300300        (void**)&base);
    301301    if (area < 0)
    302302        return;
  • src/system/kernel/debug/tracing.cpp

    diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp
    index 72cbb95..5ae6d22 100644
    a b TracingMetaData::Create(TracingMetaData*& _metaData)  
    435435    physical_address_restrictions physicalRestrictions = {};
    436436    area = create_area_etc(B_SYSTEM_TEAM, "tracing log",
    437437        kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS,
    438         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     438        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    439439        &virtualRestrictions, &physicalRestrictions,
    440440        (void**)&metaData->fTraceOutputBuffer);
    441441    if (area < 0)
    TracingMetaData::_CreateMetaDataArea(bool findPrevious, area_id& _area,  
    486486        physicalRestrictions.high_address = metaDataAddress + B_PAGE_SIZE;
    487487        area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing metadata",
    488488            B_PAGE_SIZE, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    489             CREATE_AREA_DONT_CLEAR, &virtualRestrictions, &physicalRestrictions,
    490             (void**)&metaData);
     489            CREATE_AREA_DONT_CLEAR, 0, &virtualRestrictions,
     490            &physicalRestrictions, (void**)&metaData);
    491491        if (area < 0)
    492492            continue;
    493493
    TracingMetaData::_InitPreviousTracingData()  
    550550        + ROUNDUP(kTraceOutputBufferSize + MAX_TRACE_SIZE, B_PAGE_SIZE);
    551551    area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing log",
    552552        kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS,
    553         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR,
     553        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR, 0,
    554554        &virtualRestrictions, &physicalRestrictions, NULL);
    555555    if (area < 0) {
    556556        dprintf("Failed to init tracing meta data: Mapping tracing log "
  • src/system/kernel/device_manager/dma_resources.cpp

    diff --git a/src/system/kernel/device_manager/dma_resources.cpp b/src/system/kernel/device_manager/dma_resources.cpp
    index 5c4b3de..190c952 100644
    a b DMAResource::CreateBounceBuffer(DMABounceBuffer** _buffer)  
    246246    physicalRestrictions.alignment = fRestrictions.alignment;
    247247    physicalRestrictions.boundary = fRestrictions.boundary;
    248248    area = create_area_etc(B_SYSTEM_TEAM, "dma buffer", size, B_CONTIGUOUS,
    249         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, &virtualRestrictions,
     249        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, 0, &virtualRestrictions,
    250250        &physicalRestrictions, &bounceBuffer);
    251251    if (area < B_OK)
    252252        return area;
  • src/system/kernel/elf.cpp

    diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp
    index ad3c291..bdbf3fe 100644
    a b elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)  
    19311931                virtualRestrictions.address_specification = B_EXACT_ADDRESS;
    19321932                physical_address_restrictions physicalRestrictions = {};
    19331933                id = create_area_etc(team->id, regionName, bssSize, B_NO_LOCK,
    1934                     B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
     1934                    B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
    19351935                    &physicalRestrictions, (void**)&regionAddress);
    19361936                if (id < B_OK) {
    19371937                    dprintf("error allocating bss area: %s!\n", strerror(id));
  • src/system/kernel/sem.cpp

    diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp
    index 2c460b9..6e6b26d 100644
    a b haiku_sem_init(kernel_args *args)  
    431431    physical_address_restrictions physicalRestrictions = {};
    432432    area = create_area_etc(B_SYSTEM_TEAM, "sem_table",
    433433        sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK,
    434         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     434        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    435435        &virtualRestrictions, &physicalRestrictions, (void**)&sSems);
    436436    if (area < 0)
    437437        panic("unable to allocate semaphore table!\n");
  • src/system/kernel/slab/MemoryManager.cpp

    diff --git a/src/system/kernel/slab/MemoryManager.cpp b/src/system/kernel/slab/MemoryManager.cpp
    index 3a6ac26..54523f9 100644
    a b MemoryManager::AllocateRaw(size_t size, uint32 flags, void*& _pages)  
    628628            B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    629629            ((flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0
    630630                    ? CREATE_AREA_DONT_WAIT : 0)
    631                 | CREATE_AREA_DONT_CLEAR,
     631                | CREATE_AREA_DONT_CLEAR, 0,
    632632            &virtualRestrictions, &physicalRestrictions, &_pages);
    633633
    634634        status_t result = area >= 0 ? B_OK : area;
  • src/system/kernel/team.cpp

    diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp
    index b794b07..346ae61 100644
    a b create_team_user_data(Team* team)  
    13311331    virtualRestrictions.address_specification = B_BASE_ADDRESS;
    13321332    physical_address_restrictions physicalRestrictions = {};
    13331333    team->user_data_area = create_area_etc(team->id, "user area", size,
    1334         B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
     1334        B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
    13351335        &physicalRestrictions, &address);
    13361336    if (team->user_data_area < 0)
    13371337        return team->user_data_area;
  • src/system/kernel/thread.cpp

    diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
    index e6567a1..bc903bf 100644
    a b init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)  
    781781
    782782static status_t
    783783create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
    784     size_t stackSize, size_t additionalSize, char* nameBuffer)
     784    size_t stackSize, size_t additionalSize, size_t guardSize,
     785    char* nameBuffer)
    785786{
    786787    area_id stackArea = -1;
    787788    uint8* stackBase = (uint8*)_stackBase;
    788789
    789790    if (stackBase != NULL) {
    790791        // A stack has been specified. It must be large enough to hold the
    791         // TLS space at least.
     792        // TLS space at least. Guard pages are ignored for existing stacks.
    792793        STATIC_ASSERT(TLS_SIZE < MIN_USER_STACK_SIZE);
    793794        if (stackSize < MIN_USER_STACK_SIZE)
    794795            return B_BAD_VALUE;
    795 
    796         stackBase -= TLS_SIZE;
    797     }
    798 
    799     if (stackBase == NULL) {
     796    } else {
    800797        // No user-defined stack -- allocate one. For non-main threads the stack
    801798        // will be between USER_STACK_REGION and the main thread stack area. For
    802799        // a main thread the position is fixed.
    803800
     801        guardSize = PAGE_ALIGN(guardSize);
     802        page_num_t guardPages = guardSize / B_PAGE_SIZE;
     803
    804804        if (stackSize == 0) {
    805805            // Use the default size (a different one for a main thread).
    806806            stackSize = thread->id == team->id
    807807                ? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE;
    808808        } else {
    809809            // Verify that the given stack size is large enough.
    810             if (stackSize < MIN_USER_STACK_SIZE - TLS_SIZE)
     810            if (stackSize < MIN_USER_STACK_SIZE)
    811811                return B_BAD_VALUE;
    812812
    813813            stackSize = PAGE_ALIGN(stackSize);
    814814        }
    815         stackSize += USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
    816815
    817         size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + additionalSize);
     816        size_t areaSize = PAGE_ALIGN(guardSize + stackSize + TLS_SIZE
     817            + additionalSize);
    818818
    819819        snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%ld_stack", thread->name,
    820820            thread->id);
    create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,  
    838838
    839839        stackArea = create_area_etc(team->id, nameBuffer,
    840840            areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA,
    841             0, &virtualRestrictions, &physicalRestrictions,
     841            0, guardPages, &virtualRestrictions, &physicalRestrictions,
    842842            (void**)&stackBase);
    843843        if (stackArea < 0)
    844844            return stackArea;
    create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,  
    846846
    847847    // set the stack
    848848    ThreadLocker threadLocker(thread);
    849     thread->user_stack_base = (addr_t)stackBase;
     849    thread->user_stack_base = (addr_t)stackBase + guardSize;
    850850    thread->user_stack_size = stackSize;
    851851    thread->user_stack_area = stackArea;
    852852
    thread_create_user_stack(Team* team, Thread* thread, void* stackBase,  
    860860{
    861861    char nameBuffer[B_OS_NAME_LENGTH];
    862862    return create_thread_user_stack(team, thread, stackBase, stackSize,
    863         additionalSize, nameBuffer);
     863        additionalSize, USER_STACK_GUARD_PAGES * B_PAGE_SIZE, nameBuffer);
    864864}
    865865
    866866
    thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)  
    917917    char stackName[B_OS_NAME_LENGTH];
    918918    snprintf(stackName, B_OS_NAME_LENGTH, "%s_%ld_kstack", thread->name,
    919919        thread->id);
    920     thread->kernel_stack_area = create_area(stackName,
    921         (void **)&thread->kernel_stack_base, B_ANY_KERNEL_ADDRESS,
    922         KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES  * B_PAGE_SIZE,
    923         B_FULL_LOCK,
    924         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA);
     920    virtual_address_restrictions virtualRestrictions = {};
     921    virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS;
     922    physical_address_restrictions physicalRestrictions = {};
     923   
     924    thread->kernel_stack_area = create_area_etc(B_SYSTEM_TEAM, stackName,
     925        KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
     926        B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA
     927            | B_KERNEL_STACK_AREA, 0, KERNEL_STACK_GUARD_PAGES,
     928        &virtualRestrictions, &physicalRestrictions,
     929        (void**)&thread->kernel_stack_base);
    925930
    926931    if (thread->kernel_stack_area < 0) {
    927932        // we're not yet part of a team, so we can just bail out
    thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)  
    950955        if (thread->user_stack_base == 0) {
    951956            status = create_thread_user_stack(team, thread,
    952957                attributes.stack_address, attributes.stack_size,
    953                 attributes.additional_stack_size, stackName);
     958                attributes.additional_stack_size, attributes.guard_size,
     959                stackName);
    954960            if (status != B_OK)
    955961                return status;
    956962        }
  • src/system/kernel/vm/vm.cpp

    diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp
    index c6d6829..2ffdc8f 100644
    a b vm_reserve_address_range(team_id team, void** _address, uint32 addressSpec,  
    11771177
    11781178area_id
    11791179vm_create_anonymous_area(team_id team, const char *name, addr_t size,
    1180     uint32 wiring, uint32 protection, uint32 flags,
     1180    uint32 wiring, uint32 protection, uint32 flags, page_num_t guardPages,
    11811181    const virtual_address_restrictions* virtualAddressRestrictions,
    11821182    const physical_address_restrictions* physicalAddressRestrictions,
    11831183    bool kernel, void** _address)
    vm_create_anonymous_area(team_id team, const char *name, addr_t size,  
    11861186    VMCache* cache;
    11871187    vm_page* page = NULL;
    11881188    bool isStack = (protection & B_STACK_AREA) != 0;
    1189     page_num_t guardPages;
    11901189    bool canOvercommit = false;
    11911190    uint32 pageAllocFlags = (flags & CREATE_AREA_DONT_CLEAR) == 0
    11921191        ? VM_PAGE_ALLOC_CLEAR : 0;
    vm_create_anonymous_area(team_id team, const char *name, addr_t size,  
    11951194
    11961195    size = PAGE_ALIGN(size);
    11971196
    1198     if (size == 0)
     1197    if (size == 0 || size < guardPages * B_PAGE_SIZE)
    11991198        return B_BAD_VALUE;
    12001199    if (!arch_vm_supports_protection(protection))
    12011200        return B_NOT_SUPPORTED;
    vm_create_anonymous_area(team_id team, const char *name, addr_t size,  
    13711370
    13721371    // create an anonymous cache
    13731372    // if it's a stack, make sure that two pages are available at least
    1374     guardPages = isStack ? ((protection & B_USER_PROTECTION) != 0
    1375         ? USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0;
    13761373    status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit,
    13771374        isStack ? (min_c(2, size / B_PAGE_SIZE - guardPages)) : 0, guardPages,
    13781375        wiring == B_NO_LOCK, priority);
    _vm_map_file(team_id team, const char* name, void** _address,  
    18761873        virtualRestrictions.address_specification = addressSpec;
    18771874        physical_address_restrictions physicalRestrictions = {};
    18781875        return vm_create_anonymous_area(team, name, size, B_NO_LOCK, protection,
    1879             flags, &virtualRestrictions, &physicalRestrictions, kernel,
     1876            flags, 0, &virtualRestrictions, &physicalRestrictions, kernel,
    18801877            _address);
    18811878    }
    18821879
    vm_init(kernel_args* args)  
    38863883        create_area_etc(VMAddressSpace::KernelID(), "cache info table",
    38873884            ROUNDUP(kCacheInfoTableCount * sizeof(cache_info), B_PAGE_SIZE),
    38883885            B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    3889             CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions,
    3890             (void**)&sCacheInfoTable);
     3886            CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions,
     3887            &physicalRestrictions, (void**)&sCacheInfoTable);
    38913888    }
    38923889#endif  // DEBUG_CACHE_LIST
    38933890
    clone_area(const char* name, void** _address, uint32 addressSpec,  
    58545851
    58555852area_id
    58565853create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,
    5857     uint32 protection, uint32 flags,
     5854    uint32 protection, uint32 flags, page_num_t guardPages,
    58585855    const virtual_address_restrictions* virtualAddressRestrictions,
    58595856    const physical_address_restrictions* physicalAddressRestrictions,
    58605857    void** _address)
    create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,  
    58625859    fix_protection(&protection);
    58635860
    58645861    return vm_create_anonymous_area(team, name, size, lock, protection, flags,
    5865         virtualAddressRestrictions, physicalAddressRestrictions, true,
    5866         _address);
     5862        guardPages, virtualAddressRestrictions, physicalAddressRestrictions,
     5863        true, _address);
    58675864}
    58685865
    58695866
    __create_area_haiku(const char* name, void** _address, uint32 addressSpec,  
    58785875    virtualRestrictions.address_specification = addressSpec;
    58795876    physical_address_restrictions physicalRestrictions = {};
    58805877    return vm_create_anonymous_area(VMAddressSpace::KernelID(), name, size,
    5881         lock, protection, 0, &virtualRestrictions, &physicalRestrictions, true,
    5882         _address);
     5878        lock, protection, 0, 0, &virtualRestrictions, &physicalRestrictions,
     5879        true, _address);
    58835880}
    58845881
    58855882
    _user_create_area(const char* userName, void** userAddress, uint32 addressSpec,  
    61226119    virtualRestrictions.address_specification = addressSpec;
    61236120    physical_address_restrictions physicalRestrictions = {};
    61246121    area_id area = vm_create_anonymous_area(VMAddressSpace::CurrentID(), name,
    6125         size, lock, protection, 0, &virtualRestrictions, &physicalRestrictions,
    6126         false, &address);
     6122        size, lock, protection, 0, 0, &virtualRestrictions,
     6123        &physicalRestrictions, false, &address);
    61276124
    61286125    if (area >= B_OK
    61296126        && user_memcpy(userAddress, &address, sizeof(address)) < B_OK) {
  • src/system/libroot/posix/pthread/pthread.cpp

    diff --git a/src/system/libroot/posix/pthread/pthread.cpp b/src/system/libroot/posix/pthread/pthread.cpp
    index 4c5104a..e8f1b61 100644
    a b  
    2525static const pthread_attr pthread_attr_default = {
    2626    PTHREAD_CREATE_JOINABLE,
    2727    B_NORMAL_PRIORITY,
    28     USER_STACK_SIZE
     28    USER_STACK_SIZE,
     29    USER_STACK_GUARD_PAGES * B_PAGE_SIZE
    2930};
    3031
    3132
    __pthread_init_creation_attributes(const pthread_attr_t* pthreadAttributes,  
    117118    attributes->args2 = argument2;
    118119    attributes->stack_address = NULL;
    119120    attributes->stack_size = attr->stack_size;
     121    attributes->guard_size = attr->guard_size;
    120122    attributes->pthread = thread;
    121123    attributes->flags = 0;
    122124
  • src/system/libroot/posix/pthread/pthread_attr.c

    diff --git a/src/system/libroot/posix/pthread/pthread_attr.c b/src/system/libroot/posix/pthread/pthread_attr.c
    index 3054690..8252fae 100644
    a b pthread_attr_init(pthread_attr_t *_attr)  
    3030    attr->detach_state = PTHREAD_CREATE_JOINABLE;
    3131    attr->sched_priority = B_NORMAL_PRIORITY;
    3232    attr->stack_size = USER_STACK_SIZE;
     33    attr->guard_size = USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
    3334
    3435    *_attr = attr;
    3536    return B_OK;
    pthread_attr_getschedparam(const pthread_attr_t *attr,  
    162163    return 0;
    163164}
    164165
     166
     167int
     168pthread_attr_getguardsize(const pthread_attr_t *_attr, size_t *guardsize)
     169{
     170    pthread_attr *attr;
     171
     172    if (_attr == NULL || (attr = *_attr) == NULL || guardsize == NULL)
     173        return B_BAD_VALUE;
     174
     175    *guardsize = attr->guard_size;
     176
     177    return 0;
     178}
     179
     180
     181int
     182pthread_attr_setguardsize(pthread_attr_t *_attr, size_t guardsize)
     183{
     184    pthread_attr *attr;
     185
     186    if (_attr == NULL || (attr = *_attr) == NULL)
     187        return B_BAD_VALUE;
     188
     189    attr->guard_size = guardsize;
     190
     191    return 0;
     192}