Ticket #8233: 0001-Add-support-for-pthread_attr_get-setguardsize.2.patch

File 0001-Add-support-for-pthread_attr_get-setguardsize.2.patch, 34.0 KB (added by hamish, 11 years ago)
  • headers/posix/pthread.h

    From 12c4450781a2791a68007e57af88db521526aeec Mon Sep 17 00:00:00 2001
    From: Hamish Morrison <hamishm53@gmail.com>
    Date: Sun, 1 Apr 2012 08:37:42 +0000
    Subject: [PATCH] Add support for pthread_attr_get/setguardsize()
    
    * Added the aforementioned functions.
    * create_area_etc() now takes a guard size parameter.
    * The thread_info::stack_base/end range now refers to the usable range
      only.
    ---
     headers/posix/pthread.h                            |    9 ++---
     headers/private/kernel/vm/VMCache.h                |    2 +
     headers/private/kernel/vm/vm.h                     |    4 +-
     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 +-
     src/libs/posix_error_mapper/pthread_attr.cpp       |   14 +++++++
     .../arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp |    2 +-
     src/system/kernel/arch/x86/32/descriptors.cpp      |    2 +-
     src/system/kernel/arch/x86/arch_cpu.cpp            |    2 +-
     .../arch/x86/paging/32bit/X86PagingMethod32Bit.cpp |    2 +-
     .../arch/x86/paging/pae/X86PagingMethodPAE.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                       |   40 +++++++++++++-------
     src/system/kernel/vm/VMAnonymousCache.cpp          |   21 +++++-----
     src/system/kernel/vm/VMAnonymousCache.h            |    2 +
     src/system/kernel/vm/VMAnonymousNoSwapCache.cpp    |   21 +++++-----
     src/system/kernel/vm/VMAnonymousNoSwapCache.h      |    2 +
     src/system/kernel/vm/vm.cpp                        |   37 +++++++++---------
     src/system/libroot/posix/pthread/pthread.cpp       |    4 +-
     src/system/libroot/posix/pthread/pthread_attr.c    |   28 ++++++++++++++
     29 files changed, 148 insertions(+), 87 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/VMCache.h

    diff --git a/headers/private/kernel/vm/VMCache.h b/headers/private/kernel/vm/VMCache.h
    index 06bb0b9..ffa236a 100644
    a b public:  
    117117    inline  void                IncrementWiredPagesCount();
    118118    inline  void                DecrementWiredPagesCount();
    119119
     120    virtual int32               GuardSize() { return 0; }
     121
    120122            void                AddConsumer(VMCache* consumer);
    121123
    122124            status_t            InsertAreaLocked(VMArea* area);
  • headers/private/kernel/vm/vm.h

    diff --git a/headers/private/kernel/vm/vm.h b/headers/private/kernel/vm/vm.h
    index ef1b829..bd9fd16 100644
    a b void forbid_page_faults(void);  
    7777
    7878// private kernel only extension (should be moved somewhere else):
    7979area_id create_area_etc(team_id team, const char *name, uint32 size,
    80             uint32 lock, uint32 protection, uint32 flags,
     80            uint32 lock, uint32 protection, uint32 flags, uint32 guardSize,
    8181            const virtual_address_restrictions* virtualAddressRestrictions,
    8282            const physical_address_restrictions* physicalAddressRestrictions,
    8383            void **_address);
    status_t vm_unreserve_address_range(team_id team, void *address, addr_t size);  
    9595status_t vm_reserve_address_range(team_id team, void **_address,
    9696            uint32 addressSpec, addr_t size, uint32 flags);
    9797area_id vm_create_anonymous_area(team_id team, const char* name, addr_t size,
    98             uint32 wiring, uint32 protection, uint32 flags,
     98            uint32 wiring, uint32 protection, uint32 flags, addr_t guardSize,
    9999            const virtual_address_restrictions* virtualAddressRestrictions,
    100100            const physical_address_restrictions* physicalAddressRestrictions,
    101101            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..2d55937 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_SIZE       (4 * B_PAGE_SIZE)       // 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 338a45f..ef54810 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/libs/posix_error_mapper/pthread_attr.cpp

    diff --git a/src/libs/posix_error_mapper/pthread_attr.cpp b/src/libs/posix_error_mapper/pthread_attr.cpp
    index 163220a..2783bfd 100644
    a b WRAPPER_FUNCTION(int, pthread_attr_getschedparam,  
    7373    return B_TO_POSITIVE_ERROR(sReal_pthread_attr_getschedparam(attr,
    7474        param));
    7575)
     76
     77
     78WRAPPER_FUNCTION(int, pthread_attr_getguardsize,
     79        (const pthread_attr_t *attr, size_t *guardsize),
     80    return B_TO_POSITIVE_ERROR(sReal_pthread_attr_getguardsize(attr,
     81        guardsize));
     82)
     83
     84
     85WRAPPER_FUNCTION(int, pthread_attr_setguardsize,
     86        (pthread_attr_t *attr, size_t guardsize),
     87    return B_TO_POSITIVE_ERROR(sReal_pthread_attr_setguardsize(attr,
     88        guardsize));
     89)
  • 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 fe033e0..a973bb2 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/32/descriptors.cpp

    diff --git a/src/system/kernel/arch/x86/32/descriptors.cpp b/src/system/kernel/arch/x86/32/descriptors.cpp
    index 2a957e3..465aab7 100644
    a b x86_descriptors_init_post_vm(kernel_args* args)  
    552552        physical_address_restrictions physicalRestrictions = {};
    553553        area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS,
    554554            B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
    555             &virtualRestrictions, &physicalRestrictions, (void**)&idt);
     555            0, &virtualRestrictions, &physicalRestrictions, (void**)&idt);
    556556        if (area < 0)
    557557            return area;
    558558
  • 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 155ed97..7438203 100644
    a b arch_cpu_init_post_vm(kernel_args* args)  
    792792    physical_address_restrictions physicalRestrictions = {};
    793793    create_area_etc(B_SYSTEM_TEAM, "double fault stacks",
    794794        kDoubleFaultStackSize * smp_get_num_cpus(), B_FULL_LOCK,
    795         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     795        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    796796        &virtualRestrictions, &physicalRestrictions,
    797797        (void**)&sDoubleFaultStacks);
    798798
  • 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 987f3b4..be91ed5 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 3a3115f..34258f0 100644
    a b X86PagingMethodPAE::PhysicalPageSlotPool::AllocatePool(  
    487487    physical_address_restrictions physicalRestrictions = {};
    488488    area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
    489489        PAGE_ALIGN(areaSize), B_FULL_LOCK,
    490         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     490        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    491491        &virtualRestrictions, &physicalRestrictions, &data);
    492492    if (dataArea < 0)
    493493        return dataArea;
  • 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 996f521..efdd734 100644
    a b debug_heap_init()  
    309309    physical_address_restrictions physicalRestrictions = {};
    310310    area_id area = create_area_etc(B_SYSTEM_TEAM, "kdebug heap", KDEBUG_HEAP,
    311311        B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    312         CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions,
     312        CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, &physicalRestrictions,
    313313        (void**)&base);
    314314    if (area < 0)
    315315        return;
  • src/system/kernel/debug/tracing.cpp

    diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp
    index 02b55c7..e52ffb7 100644
    a b TracingMetaData::Create(TracingMetaData*& _metaData)  
    452452    physical_address_restrictions physicalRestrictions = {};
    453453    area = create_area_etc(B_SYSTEM_TEAM, "tracing log",
    454454        kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS,
    455         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     455        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    456456        &virtualRestrictions, &physicalRestrictions,
    457457        (void**)&metaData->fTraceOutputBuffer);
    458458    if (area < 0)
    TracingMetaData::_CreateMetaDataArea(bool findPrevious, area_id& _area,  
    503503        physicalRestrictions.high_address = metaDataAddress + B_PAGE_SIZE;
    504504        area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing metadata",
    505505            B_PAGE_SIZE, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    506             CREATE_AREA_DONT_CLEAR, &virtualRestrictions, &physicalRestrictions,
    507             (void**)&metaData);
     506            CREATE_AREA_DONT_CLEAR, 0, &virtualRestrictions,
     507            &physicalRestrictions, (void**)&metaData);
    508508        if (area < 0)
    509509            continue;
    510510
    TracingMetaData::_InitPreviousTracingData()  
    567567        + ROUNDUP(kTraceOutputBufferSize + MAX_TRACE_SIZE, B_PAGE_SIZE);
    568568    area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing log",
    569569        kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS,
    570         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR,
     570        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR, 0,
    571571        &virtualRestrictions, &physicalRestrictions, NULL);
    572572    if (area < 0) {
    573573        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 7e334f4..71753c8 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 19d5e55..0bb496f 100644
    a b elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)  
    19431943                virtualRestrictions.address_specification = B_EXACT_ADDRESS;
    19441944                physical_address_restrictions physicalRestrictions = {};
    19451945                id = create_area_etc(team->id, regionName, bssSize, B_NO_LOCK,
    1946                     B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
     1946                    B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
    19471947                    &physicalRestrictions, (void**)&regionAddress);
    19481948                if (id < B_OK) {
    19491949                    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 13fe243..0b761c2 100644
    a b haiku_sem_init(kernel_args *args)  
    432432    physical_address_restrictions physicalRestrictions = {};
    433433    area = create_area_etc(B_SYSTEM_TEAM, "sem_table",
    434434        sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK,
    435         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     435        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    436436        &virtualRestrictions, &physicalRestrictions, (void**)&sSems);
    437437    if (area < 0)
    438438        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 39d6d57..1dab8fb 100644
    a b MemoryManager::AllocateRaw(size_t size, uint32 flags, void*& _pages)  
    627627            B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    628628            ((flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0
    629629                    ? CREATE_AREA_DONT_WAIT : 0)
    630                 | CREATE_AREA_DONT_CLEAR,
     630                | CREATE_AREA_DONT_CLEAR, 0,
    631631            &virtualRestrictions, &physicalRestrictions, &_pages);
    632632
    633633        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 e492bcd..381be36 100644
    a b create_team_user_data(Team* team)  
    13331333    virtualRestrictions.address_specification = B_BASE_ADDRESS;
    13341334    physical_address_restrictions physicalRestrictions = {};
    13351335    team->user_data_area = create_area_etc(team->id, "user area", size,
    1336         B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
     1336        B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
    13371337        &physicalRestrictions, &address);
    13381338    if (team->user_data_area < 0)
    13391339        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 e0eae26..02a574e 100644
    a b ThreadCreationAttributes::ThreadCreationAttributes(thread_func function,  
    524524    this->args2 = NULL;
    525525    this->stack_address = NULL;
    526526    this->stack_size = 0;
     527    this->guard_size = 0;
    527528    this->pthread = NULL;
    528529    this->flags = 0;
    529530    this->team = team >= 0 ? team : team_get_kernel_team()->id;
    init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)  
    781782
    782783static status_t
    783784create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
    784     size_t stackSize, size_t additionalSize, char* nameBuffer)
     785    size_t stackSize, size_t additionalSize, size_t guardSize,
     786    char* nameBuffer)
    785787{
    786788    area_id stackArea = -1;
    787789    uint8* stackBase = (uint8*)_stackBase;
    788790
    789791    if (stackBase != NULL) {
    790792        // A stack has been specified. It must be large enough to hold the
    791         // TLS space at least.
     793        // TLS space at least. Guard pages are ignored for existing stacks.
    792794        STATIC_ASSERT(TLS_SIZE < MIN_USER_STACK_SIZE);
    793795        if (stackSize < MIN_USER_STACK_SIZE)
    794796            return B_BAD_VALUE;
    create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,  
    799801        // will be between USER_STACK_REGION and the main thread stack area. For
    800802        // a main thread the position is fixed.
    801803
     804        guardSize = PAGE_ALIGN(guardSize);
     805
    802806        if (stackSize == 0) {
    803807            // Use the default size (a different one for a main thread).
    804808            stackSize = thread->id == team->id
    805809                ? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE;
    806810        } else {
    807811            // Verify that the given stack size is large enough.
    808             if (stackSize < MIN_USER_STACK_SIZE - TLS_SIZE)
     812            if (stackSize < MIN_USER_STACK_SIZE)
    809813                return B_BAD_VALUE;
    810814
    811815            stackSize = PAGE_ALIGN(stackSize);
    812816        }
    813         stackSize += USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
    814817
    815         size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + additionalSize);
     818        size_t areaSize = PAGE_ALIGN(guardSize + stackSize + TLS_SIZE
     819            + additionalSize);
    816820
    817821        snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_stack",
    818822            thread->name, thread->id);
    create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,  
    836840
    837841        stackArea = create_area_etc(team->id, nameBuffer,
    838842            areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA,
    839             0, &virtualRestrictions, &physicalRestrictions,
     843            0, guardSize, &virtualRestrictions, &physicalRestrictions,
    840844            (void**)&stackBase);
    841845        if (stackArea < 0)
    842846            return stackArea;
    create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,  
    844848
    845849    // set the stack
    846850    ThreadLocker threadLocker(thread);
     851#ifdef STACK_GROWS_DOWNWARDS
     852    thread->user_stack_base = (addr_t)stackBase + guardSize;
     853#else
    847854    thread->user_stack_base = (addr_t)stackBase;
     855#endif
    848856    thread->user_stack_size = stackSize;
    849857    thread->user_stack_area = stackArea;
    850858
    thread_create_user_stack(Team* team, Thread* thread, void* stackBase,  
    858866{
    859867    char nameBuffer[B_OS_NAME_LENGTH];
    860868    return create_thread_user_stack(team, thread, stackBase, stackSize,
    861         additionalSize, nameBuffer);
     869        additionalSize, USER_STACK_GUARD_SIZE, nameBuffer);
    862870}
    863871
    864872
    thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)  
    915923    char stackName[B_OS_NAME_LENGTH];
    916924    snprintf(stackName, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_kstack",
    917925        thread->name, thread->id);
    918     thread->kernel_stack_area = create_area(stackName,
    919         (void **)&thread->kernel_stack_base, B_ANY_KERNEL_ADDRESS,
    920         KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES  * B_PAGE_SIZE,
    921         B_FULL_LOCK,
    922         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA);
     926    virtual_address_restrictions virtualRestrictions = {};
     927    virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS;
     928    physical_address_restrictions physicalRestrictions = {};
     929
     930    thread->kernel_stack_area = create_area_etc(B_SYSTEM_TEAM, stackName,
     931        KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
     932        B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA
     933            | B_KERNEL_STACK_AREA, 0, KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
     934        &virtualRestrictions, &physicalRestrictions,
     935        (void**)&thread->kernel_stack_base);
    923936
    924937    if (thread->kernel_stack_area < 0) {
    925938        // we're not yet part of a team, so we can just bail out
    thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)  
    948961        if (thread->user_stack_base == 0) {
    949962            status = create_thread_user_stack(team, thread,
    950963                attributes.stack_address, attributes.stack_size,
    951                 attributes.additional_stack_size, stackName);
     964                attributes.additional_stack_size, attributes.guard_size,
     965                stackName);
    952966            if (status != B_OK)
    953967                return status;
    954968        }
  • src/system/kernel/vm/VMAnonymousCache.cpp

    diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp
    index 78925e9..8302f99 100644
    a b VMAnonymousCache::MaxPagesPerAsyncWrite() const  
    787787status_t
    788788VMAnonymousCache::Fault(struct VMAddressSpace* aspace, off_t offset)
    789789{
    790     if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) {
    791         if (fGuardedSize > 0) {
    792             uint32 guardOffset;
     790    if (fGuardedSize > 0) {
     791        uint32 guardOffset;
    793792
    794793#ifdef STACK_GROWS_DOWNWARDS
    795             guardOffset = 0;
     794        guardOffset = 0;
    796795#elif defined(STACK_GROWS_UPWARDS)
    797             guardOffset = virtual_size - fGuardedSize;
     796        guardOffset = virtual_size - fGuardedSize;
    798797#else
    799798#   error Stack direction has not been defined in arch_config.h
    800799#endif
    801 
    802             // report stack fault, guard page hit!
    803             if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
    804                 TRACE(("stack overflow!\n"));
    805                 return B_BAD_ADDRESS;
    806             }
     800        // report stack fault, guard page hit!
     801        if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
     802            TRACE(("stack overflow!\n"));
     803            return B_BAD_ADDRESS;
    807804        }
     805    }
    808806
     807    if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) {
    809808        if (fPrecommittedPages == 0) {
    810809            // never commit more than needed
    811810            if (committed_size / B_PAGE_SIZE > page_count)
  • src/system/kernel/vm/VMAnonymousCache.h

    diff --git a/src/system/kernel/vm/VMAnonymousCache.h b/src/system/kernel/vm/VMAnonymousCache.h
    index a3d51ad..065f422 100644
    a b public:  
    4545    virtual bool                HasPage(off_t offset);
    4646    virtual bool                DebugHasPage(off_t offset);
    4747
     48    virtual int32               GuardSize() { return fGuardedSize; }
     49
    4850    virtual status_t            Read(off_t offset, const generic_io_vec* vecs,
    4951                                    size_t count, uint32 flags,
    5052                                    generic_size_t* _numBytes);
  • src/system/kernel/vm/VMAnonymousNoSwapCache.cpp

    diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp b/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp
    index bd8ec84d..1de023a 100644
    a b VMAnonymousNoSwapCache::Write(off_t offset, const iovec* vecs, size_t count,  
    120120status_t
    121121VMAnonymousNoSwapCache::Fault(struct VMAddressSpace* aspace, off_t offset)
    122122{
    123     if (fCanOvercommit) {
    124         if (fGuardedSize > 0) {
    125             uint32 guardOffset;
     123    if (fGuardedSize > 0) {
     124        uint32 guardOffset;
    126125
    127126#ifdef STACK_GROWS_DOWNWARDS
    128             guardOffset = 0;
     127        guardOffset = 0;
    129128#elif defined(STACK_GROWS_UPWARDS)
    130             guardOffset = virtual_size - fGuardedSize;
     129        guardOffset = virtual_size - fGuardedSize;
    131130#else
    132131#   error Stack direction has not been defined in arch_config.h
    133132#endif
    134 
    135             // report stack fault, guard page hit!
    136             if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
    137                 TRACE(("stack overflow!\n"));
    138                 return B_BAD_ADDRESS;
    139             }
     133        // report stack fault, guard page hit!
     134        if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
     135            TRACE(("stack overflow!\n"));
     136            return B_BAD_ADDRESS;
    140137        }
     138    }
    141139
     140    if (fCanOvercommit) {
    142141        if (fPrecommittedPages == 0) {
    143142            // never commit more than needed
    144143            if (committed_size / B_PAGE_SIZE > page_count)
  • src/system/kernel/vm/VMAnonymousNoSwapCache.h

    diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.h b/src/system/kernel/vm/VMAnonymousNoSwapCache.h
    index c9b839e..c9250ed 100644
    a b public:  
    2525    virtual status_t            Commit(off_t size, int priority);
    2626    virtual bool                HasPage(off_t offset);
    2727
     28    virtual int32               GuardSize() { return fGuardedSize; }
     29
    2830    virtual status_t            Read(off_t offset, const iovec* vecs,
    2931                                    size_t count, uint32 flags,
    3032                                    size_t* _numBytes);
  • src/system/kernel/vm/vm.cpp

    diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp
    index 1559491..6e809b6 100644
    a b map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset,  
    817817        VMCache* newCache;
    818818
    819819        // create an anonymous cache
    820         bool isStack = (protection & B_STACK_AREA) != 0;
    821820        status = VMCacheFactory::CreateAnonymousCache(newCache,
    822             isStack || (protection & B_OVERCOMMITTING_AREA) != 0, 0,
    823             isStack ? USER_STACK_GUARD_PAGES : 0, true, VM_PRIORITY_USER);
     821            (protection & B_STACK_AREA) != 0
     822                || (protection & B_OVERCOMMITTING_AREA) != 0, 0,
     823            cache->GuardSize() / B_PAGE_SIZE, true, VM_PRIORITY_USER);
    824824        if (status != B_OK)
    825825            goto err1;
    826826
    vm_reserve_address_range(team_id team, void** _address, uint32 addressSpec,  
    11781178
    11791179area_id
    11801180vm_create_anonymous_area(team_id team, const char *name, addr_t size,
    1181     uint32 wiring, uint32 protection, uint32 flags,
     1181    uint32 wiring, uint32 protection, uint32 flags, addr_t guardSize,
    11821182    const virtual_address_restrictions* virtualAddressRestrictions,
    11831183    const physical_address_restrictions* physicalAddressRestrictions,
    11841184    bool kernel, void** _address)
    vm_create_anonymous_area(team_id team, const char *name, addr_t size,  
    11961196        team, name, size));
    11971197
    11981198    size = PAGE_ALIGN(size);
     1199    guardSize = PAGE_ALIGN(guardSize);
     1200    guardPages = guardSize / B_PAGE_SIZE;
    11991201
    1200     if (size == 0)
     1202    if (size == 0 || size < guardSize)
    12011203        return B_BAD_VALUE;
    12021204    if (!arch_vm_supports_protection(protection))
    12031205        return B_NOT_SUPPORTED;
    vm_create_anonymous_area(team_id team, const char *name, addr_t size,  
    13731375
    13741376    // create an anonymous cache
    13751377    // if it's a stack, make sure that two pages are available at least
    1376     guardPages = isStack ? ((protection & B_USER_PROTECTION) != 0
    1377         ? USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0;
    13781378    status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit,
    13791379        isStack ? (min_c(2, size / B_PAGE_SIZE - guardPages)) : 0, guardPages,
    13801380        wiring == B_NO_LOCK, priority);
    _vm_map_file(team_id team, const char* name, void** _address,  
    18791879        virtualRestrictions.address_specification = addressSpec;
    18801880        physical_address_restrictions physicalRestrictions = {};
    18811881        return vm_create_anonymous_area(team, name, size, B_NO_LOCK, protection,
    1882             flags, &virtualRestrictions, &physicalRestrictions, kernel,
     1882            flags, 0, &virtualRestrictions, &physicalRestrictions, kernel,
    18831883            _address);
    18841884    }
    18851885
    vm_copy_on_write_area(VMCache* lowerCache,  
    23052305
    23062306    // create an anonymous cache
    23072307    status_t status = VMCacheFactory::CreateAnonymousCache(upperCache, false, 0,
    2308         0, dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL,
     2308        lowerCache->GuardSize() / B_PAGE_SIZE,
     2309        dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL,
    23092310        VM_PRIORITY_USER);
    23102311    if (status != B_OK)
    23112312        return status;
    vm_init(kernel_args* args)  
    38933894        create_area_etc(VMAddressSpace::KernelID(), "cache info table",
    38943895            ROUNDUP(kCacheInfoTableCount * sizeof(cache_info), B_PAGE_SIZE),
    38953896            B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    3896             CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions,
    3897             (void**)&sCacheInfoTable);
     3897            CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions,
     3898            &physicalRestrictions, (void**)&sCacheInfoTable);
    38983899    }
    38993900#endif  // DEBUG_CACHE_LIST
    39003901
    clone_area(const char* name, void** _address, uint32 addressSpec,  
    58635864
    58645865area_id
    58655866create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,
    5866     uint32 protection, uint32 flags,
     5867    uint32 protection, uint32 flags, uint32 guardSize,
    58675868    const virtual_address_restrictions* virtualAddressRestrictions,
    58685869    const physical_address_restrictions* physicalAddressRestrictions,
    58695870    void** _address)
    create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,  
    58715872    fix_protection(&protection);
    58725873
    58735874    return vm_create_anonymous_area(team, name, size, lock, protection, flags,
    5874         virtualAddressRestrictions, physicalAddressRestrictions, true,
    5875         _address);
     5875        guardSize, virtualAddressRestrictions, physicalAddressRestrictions,
     5876        true, _address);
    58765877}
    58775878
    58785879
    __create_area_haiku(const char* name, void** _address, uint32 addressSpec,  
    58875888    virtualRestrictions.address_specification = addressSpec;
    58885889    physical_address_restrictions physicalRestrictions = {};
    58895890    return vm_create_anonymous_area(VMAddressSpace::KernelID(), name, size,
    5890         lock, protection, 0, &virtualRestrictions, &physicalRestrictions, true,
    5891         _address);
     5891        lock, protection, 0, 0, &virtualRestrictions, &physicalRestrictions,
     5892        true, _address);
    58925893}
    58935894
    58945895
    _user_create_area(const char* userName, void** userAddress, uint32 addressSpec,  
    61316132    virtualRestrictions.address_specification = addressSpec;
    61326133    physical_address_restrictions physicalRestrictions = {};
    61336134    area_id area = vm_create_anonymous_area(VMAddressSpace::CurrentID(), name,
    6134         size, lock, protection, 0, &virtualRestrictions, &physicalRestrictions,
    6135         false, &address);
     6135        size, lock, protection, 0, 0, &virtualRestrictions,
     6136        &physicalRestrictions, false, &address);
    61366137
    61376138    if (area >= B_OK
    61386139        && 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..15c2516 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_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..f6a15ff 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_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}