-
From 3c09cb1afb168200c7fa0889c3eb4f1628a47973 Mon Sep 17 00:00:00 2001
From: Hamish Morrison <hamish@lavabit.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/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 | 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 ++++++++++++++
30 files changed, 149 insertions(+), 88 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,
|
185 | 185 | extern int pthread_attr_setschedparam(pthread_attr_t *attr, |
186 | 186 | const struct sched_param *param); |
187 | 187 | |
| 188 | extern int pthread_attr_getguardsize(const pthread_attr_t *attr, |
| 189 | size_t *guardsize); |
| 190 | extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); |
| 191 | |
188 | 192 | #if 0 /* Unimplemented attribute functions: */ |
189 | 193 | |
190 | 194 | /* [TPS] */ |
… |
… |
extern int pthread_attr_getschedpolicy(const pthread_attr_t *attr,
|
196 | 200 | int *policy); |
197 | 201 | extern int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); |
198 | 202 | |
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 | | |
204 | 203 | /* [TSA] */ |
205 | 204 | extern int pthread_attr_getstackaddr(const pthread_attr_t *attr, |
206 | 205 | void **stackaddr); |
-
diff --git a/headers/private/kernel/vm/VMCache.h b/headers/private/kernel/vm/VMCache.h
index 06bb0b9..ffa236a 100644
a
|
b
|
public:
|
117 | 117 | inline void IncrementWiredPagesCount(); |
118 | 118 | inline void DecrementWiredPagesCount(); |
119 | 119 | |
| 120 | virtual int32 GuardSize() { return 0; } |
| 121 | |
120 | 122 | void AddConsumer(VMCache* consumer); |
121 | 123 | |
122 | 124 | status_t InsertAreaLocked(VMArea* area); |
-
diff --git a/headers/private/kernel/vm/vm.h b/headers/private/kernel/vm/vm.h
index 9163e3b..7bdcee1 100644
a
|
b
|
void forbid_page_faults(void);
|
77 | 77 | |
78 | 78 | // private kernel only extension (should be moved somewhere else): |
79 | 79 | area_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, |
81 | 81 | const virtual_address_restrictions* virtualAddressRestrictions, |
82 | 82 | const physical_address_restrictions* physicalAddressRestrictions, |
83 | 83 | void **_address); |
… |
… |
status_t vm_unreserve_address_range(team_id team, void *address, addr_t size);
|
95 | 95 | status_t vm_reserve_address_range(team_id team, void **_address, |
96 | 96 | uint32 addressSpec, addr_t size, uint32 flags); |
97 | 97 | area_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, |
99 | 99 | const virtual_address_restrictions* virtualAddressRestrictions, |
100 | 100 | const physical_address_restrictions* physicalAddressRestrictions, |
101 | 101 | bool kernel, void** _address); |
-
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 {
|
40 | 40 | int32 detach_state; |
41 | 41 | int32 sched_priority; |
42 | 42 | size_t stack_size; |
| 43 | size_t guard_size; |
43 | 44 | } pthread_attr; |
44 | 45 | |
45 | 46 | typedef struct _pthread_rwlockattr { |
-
diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h
index 9f1b527..2d55937 100644
a
|
b
|
|
12 | 12 | |
13 | 13 | |
14 | 14 | /** 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 |
23 | 20 | |
24 | 21 | |
25 | 22 | // The type of object a thread blocks on (thread::wait::type, set by |
… |
… |
struct thread_creation_attributes {
|
50 | 47 | void* args2; |
51 | 48 | void* stack_address; |
52 | 49 | size_t stack_size; |
| 50 | size_t guard_size; |
53 | 51 | pthread_t pthread; |
54 | 52 | uint32 flags; |
55 | 53 | }; |
-
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)
|
195 | 195 | // TODO: Use 64 bit addresses, if possible! |
196 | 196 | #endif |
197 | 197 | 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, |
199 | 199 | (void**)&buffer->address); |
200 | 200 | |
201 | 201 | if (buffer->area < 0) { |
-
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)
|
74 | 74 | physical_address_restrictions physicalRestrictions = {}; |
75 | 75 | physicalRestrictions.alignment = buffer_size; |
76 | 76 | 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, |
78 | 78 | &physicalRestrictions, &address); |
79 | 79 | // TODO: Use B_CONTIGUOUS, if possible! |
80 | 80 | |
-
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,
|
37 | 37 | |
38 | 38 | void* address; |
39 | 39 | 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, |
41 | 41 | &virtualRestrictions, &physicalRestrictions, &address); |
42 | 42 | if (area < 0) |
43 | 43 | return NULL; |
-
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,
|
73 | 73 | return B_TO_POSITIVE_ERROR(sReal_pthread_attr_getschedparam(attr, |
74 | 74 | param)); |
75 | 75 | ) |
| 76 | |
| 77 | |
| 78 | WRAPPER_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 | |
| 85 | WRAPPER_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 | ) |
-
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(
|
197 | 197 | physical_address_restrictions physicalRestrictions = {}; |
198 | 198 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
199 | 199 | 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, |
201 | 201 | &virtualRestrictions, &physicalRestrictions, &data); |
202 | 202 | if (dataArea < 0) |
203 | 203 | return dataArea; |
-
diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp
index c199afc..313a68b 100644
a
|
b
|
arch_cpu_init_post_vm(kernel_args *args)
|
765 | 765 | physical_address_restrictions physicalRestrictions = {}; |
766 | 766 | create_area_etc(B_SYSTEM_TEAM, "double fault stacks", |
767 | 767 | kDoubleFaultStackSize * smp_get_num_cpus(), B_FULL_LOCK, |
768 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 768 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
769 | 769 | &virtualRestrictions, &physicalRestrictions, |
770 | 770 | (void**)&sDoubleFaultStacks); |
771 | 771 | |
-
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)
|
873 | 873 | virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; |
874 | 874 | physical_address_restrictions physicalRestrictions = {}; |
875 | 875 | 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, |
877 | 877 | &virtualRestrictions, &physicalRestrictions, (void**)&idt); |
878 | 878 | if (area < 0) |
879 | 879 | return area; |
-
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(
|
195 | 195 | physical_address_restrictions physicalRestrictions = {}; |
196 | 196 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
197 | 197 | 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, |
199 | 199 | &virtualRestrictions, &physicalRestrictions, &data); |
200 | 200 | if (dataArea < 0) |
201 | 201 | return dataArea; |
-
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(
|
486 | 486 | physical_address_restrictions physicalRestrictions = {}; |
487 | 487 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
488 | 488 | 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, |
490 | 490 | &virtualRestrictions, &physicalRestrictions, &data); |
491 | 491 | if (dataArea < 0) |
492 | 492 | return dataArea; |
-
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)
|
552 | 552 | virtualRestrictions.address_specification = B_EXACT_ADDRESS; |
553 | 553 | physical_address_restrictions physicalRestrictions = {}; |
554 | 554 | 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, |
556 | 556 | &physicalRestrictions, &address); |
557 | 557 | if (state->ram_area < B_OK) { |
558 | 558 | ret = state->ram_area; |
-
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()
|
296 | 296 | physical_address_restrictions physicalRestrictions = {}; |
297 | 297 | area_id area = create_area_etc(B_SYSTEM_TEAM, "kdebug heap", KDEBUG_HEAP, |
298 | 298 | 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, |
300 | 300 | (void**)&base); |
301 | 301 | if (area < 0) |
302 | 302 | return; |
-
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)
|
435 | 435 | physical_address_restrictions physicalRestrictions = {}; |
436 | 436 | area = create_area_etc(B_SYSTEM_TEAM, "tracing log", |
437 | 437 | 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, |
439 | 439 | &virtualRestrictions, &physicalRestrictions, |
440 | 440 | (void**)&metaData->fTraceOutputBuffer); |
441 | 441 | if (area < 0) |
… |
… |
TracingMetaData::_CreateMetaDataArea(bool findPrevious, area_id& _area,
|
486 | 486 | physicalRestrictions.high_address = metaDataAddress + B_PAGE_SIZE; |
487 | 487 | area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing metadata", |
488 | 488 | 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); |
491 | 491 | if (area < 0) |
492 | 492 | continue; |
493 | 493 | |
… |
… |
TracingMetaData::_InitPreviousTracingData()
|
550 | 550 | + ROUNDUP(kTraceOutputBufferSize + MAX_TRACE_SIZE, B_PAGE_SIZE); |
551 | 551 | area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing log", |
552 | 552 | 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, |
554 | 554 | &virtualRestrictions, &physicalRestrictions, NULL); |
555 | 555 | if (area < 0) { |
556 | 556 | dprintf("Failed to init tracing meta data: Mapping tracing log " |
-
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)
|
246 | 246 | physicalRestrictions.alignment = fRestrictions.alignment; |
247 | 247 | physicalRestrictions.boundary = fRestrictions.boundary; |
248 | 248 | 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, |
250 | 250 | &physicalRestrictions, &bounceBuffer); |
251 | 251 | if (area < B_OK) |
252 | 252 | return area; |
-
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)
|
1931 | 1931 | virtualRestrictions.address_specification = B_EXACT_ADDRESS; |
1932 | 1932 | physical_address_restrictions physicalRestrictions = {}; |
1933 | 1933 | 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, |
1935 | 1935 | &physicalRestrictions, (void**)®ionAddress); |
1936 | 1936 | if (id < B_OK) { |
1937 | 1937 | dprintf("error allocating bss area: %s!\n", strerror(id)); |
-
diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp
index ad32ddd..3803a6d 100644
a
|
b
|
haiku_sem_init(kernel_args *args)
|
431 | 431 | physical_address_restrictions physicalRestrictions = {}; |
432 | 432 | area = create_area_etc(B_SYSTEM_TEAM, "sem_table", |
433 | 433 | 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, |
435 | 435 | &virtualRestrictions, &physicalRestrictions, (void**)&sSems); |
436 | 436 | if (area < 0) |
437 | 437 | panic("unable to allocate semaphore table!\n"); |
-
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)
|
628 | 628 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
629 | 629 | ((flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0 |
630 | 630 | ? CREATE_AREA_DONT_WAIT : 0) |
631 | | | CREATE_AREA_DONT_CLEAR, |
| 631 | | CREATE_AREA_DONT_CLEAR, 0, |
632 | 632 | &virtualRestrictions, &physicalRestrictions, &_pages); |
633 | 633 | |
634 | 634 | status_t result = area >= 0 ? B_OK : area; |
-
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)
|
1331 | 1331 | virtualRestrictions.address_specification = B_BASE_ADDRESS; |
1332 | 1332 | physical_address_restrictions physicalRestrictions = {}; |
1333 | 1333 | 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, |
1335 | 1335 | &physicalRestrictions, &address); |
1336 | 1336 | if (team->user_data_area < 0) |
1337 | 1337 | return team->user_data_area; |
-
diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
index 6c95268..bb14658 100644
a
|
b
|
ThreadCreationAttributes::ThreadCreationAttributes(thread_func function,
|
524 | 524 | this->args2 = NULL; |
525 | 525 | this->stack_address = NULL; |
526 | 526 | this->stack_size = 0; |
| 527 | this->guard_size = 0; |
527 | 528 | this->pthread = NULL; |
528 | 529 | this->flags = 0; |
529 | 530 | this->team = team >= 0 ? team : team_get_kernel_team()->id; |
… |
… |
init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)
|
781 | 782 | |
782 | 783 | static status_t |
783 | 784 | create_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) |
785 | 787 | { |
786 | 788 | area_id stackArea = -1; |
787 | 789 | uint8* stackBase = (uint8*)_stackBase; |
788 | 790 | |
789 | 791 | if (stackBase != NULL) { |
790 | 792 | // 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. |
792 | 794 | STATIC_ASSERT(TLS_SIZE < MIN_USER_STACK_SIZE); |
793 | 795 | if (stackSize < MIN_USER_STACK_SIZE) |
794 | 796 | return B_BAD_VALUE; |
… |
… |
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
|
799 | 801 | // will be between USER_STACK_REGION and the main thread stack area. For |
800 | 802 | // a main thread the position is fixed. |
801 | 803 | |
| 804 | guardSize = PAGE_ALIGN(guardSize); |
| 805 | |
802 | 806 | if (stackSize == 0) { |
803 | 807 | // Use the default size (a different one for a main thread). |
804 | 808 | stackSize = thread->id == team->id |
805 | 809 | ? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE; |
806 | 810 | } else { |
807 | 811 | // 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) |
809 | 813 | return B_BAD_VALUE; |
810 | 814 | |
811 | 815 | stackSize = PAGE_ALIGN(stackSize); |
812 | 816 | } |
813 | | stackSize += USER_STACK_GUARD_PAGES * B_PAGE_SIZE; |
814 | 817 | |
815 | | size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + additionalSize); |
| 818 | size_t areaSize = PAGE_ALIGN(guardSize + stackSize + TLS_SIZE |
| 819 | + additionalSize); |
816 | 820 | |
817 | 821 | snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%ld_stack", thread->name, |
818 | 822 | thread->id); |
… |
… |
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
|
836 | 840 | |
837 | 841 | stackArea = create_area_etc(team->id, nameBuffer, |
838 | 842 | areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, |
839 | | 0, &virtualRestrictions, &physicalRestrictions, |
| 843 | 0, guardSize, &virtualRestrictions, &physicalRestrictions, |
840 | 844 | (void**)&stackBase); |
841 | 845 | if (stackArea < 0) |
842 | 846 | return stackArea; |
… |
… |
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
|
844 | 848 | |
845 | 849 | // set the stack |
846 | 850 | ThreadLocker threadLocker(thread); |
| 851 | #ifdef STACK_GROWS_DOWNWARDS |
| 852 | thread->user_stack_base = (addr_t)stackBase + guardSize; |
| 853 | #else |
847 | 854 | thread->user_stack_base = (addr_t)stackBase; |
| 855 | #endif |
848 | 856 | thread->user_stack_size = stackSize; |
849 | 857 | thread->user_stack_area = stackArea; |
850 | 858 | |
… |
… |
thread_create_user_stack(Team* team, Thread* thread, void* stackBase,
|
858 | 866 | { |
859 | 867 | char nameBuffer[B_OS_NAME_LENGTH]; |
860 | 868 | return create_thread_user_stack(team, thread, stackBase, stackSize, |
861 | | additionalSize, nameBuffer); |
| 869 | additionalSize, USER_STACK_GUARD_SIZE, nameBuffer); |
862 | 870 | } |
863 | 871 | |
864 | 872 | |
… |
… |
thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
|
915 | 923 | char stackName[B_OS_NAME_LENGTH]; |
916 | 924 | snprintf(stackName, B_OS_NAME_LENGTH, "%s_%ld_kstack", thread->name, |
917 | 925 | 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); |
923 | 936 | |
924 | 937 | if (thread->kernel_stack_area < 0) { |
925 | 938 | // we're not yet part of a team, so we can just bail out |
… |
… |
thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
|
948 | 961 | if (thread->user_stack_base == 0) { |
949 | 962 | status = create_thread_user_stack(team, thread, |
950 | 963 | attributes.stack_address, attributes.stack_size, |
951 | | attributes.additional_stack_size, stackName); |
| 964 | attributes.additional_stack_size, attributes.guard_size, |
| 965 | stackName); |
952 | 966 | if (status != B_OK) |
953 | 967 | return status; |
954 | 968 | } |
-
diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp
index d9047df..8afaa74 100644
a
|
b
|
VMAnonymousCache::MaxPagesPerAsyncWrite() const
|
767 | 767 | status_t |
768 | 768 | VMAnonymousCache::Fault(struct VMAddressSpace* aspace, off_t offset) |
769 | 769 | { |
770 | | if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) { |
771 | | if (fGuardedSize > 0) { |
772 | | uint32 guardOffset; |
| 770 | if (fGuardedSize > 0) { |
| 771 | uint32 guardOffset; |
773 | 772 | |
774 | 773 | #ifdef STACK_GROWS_DOWNWARDS |
775 | | guardOffset = 0; |
| 774 | guardOffset = 0; |
776 | 775 | #elif defined(STACK_GROWS_UPWARDS) |
777 | | guardOffset = virtual_size - fGuardedSize; |
| 776 | guardOffset = virtual_size - fGuardedSize; |
778 | 777 | #else |
779 | 778 | # error Stack direction has not been defined in arch_config.h |
780 | 779 | #endif |
781 | | |
782 | | // report stack fault, guard page hit! |
783 | | if (offset >= guardOffset && offset < guardOffset + fGuardedSize) { |
784 | | TRACE(("stack overflow!\n")); |
785 | | return B_BAD_ADDRESS; |
786 | | } |
| 780 | // report stack fault, guard page hit! |
| 781 | if (offset >= guardOffset && offset < guardOffset + fGuardedSize) { |
| 782 | TRACE(("stack overflow!\n")); |
| 783 | return B_BAD_ADDRESS; |
787 | 784 | } |
| 785 | } |
788 | 786 | |
| 787 | if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) { |
789 | 788 | if (fPrecommittedPages == 0) { |
790 | 789 | // never commit more than needed |
791 | 790 | if (committed_size / B_PAGE_SIZE > page_count) |
-
diff --git a/src/system/kernel/vm/VMAnonymousCache.h b/src/system/kernel/vm/VMAnonymousCache.h
index a3d51ad..065f422 100644
a
|
b
|
public:
|
45 | 45 | virtual bool HasPage(off_t offset); |
46 | 46 | virtual bool DebugHasPage(off_t offset); |
47 | 47 | |
| 48 | virtual int32 GuardSize() { return fGuardedSize; } |
| 49 | |
48 | 50 | virtual status_t Read(off_t offset, const generic_io_vec* vecs, |
49 | 51 | size_t count, uint32 flags, |
50 | 52 | generic_size_t* _numBytes); |
-
diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp b/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp
index bd8ec84..1de023a 100644
a
|
b
|
VMAnonymousNoSwapCache::Write(off_t offset, const iovec* vecs, size_t count,
|
120 | 120 | status_t |
121 | 121 | VMAnonymousNoSwapCache::Fault(struct VMAddressSpace* aspace, off_t offset) |
122 | 122 | { |
123 | | if (fCanOvercommit) { |
124 | | if (fGuardedSize > 0) { |
125 | | uint32 guardOffset; |
| 123 | if (fGuardedSize > 0) { |
| 124 | uint32 guardOffset; |
126 | 125 | |
127 | 126 | #ifdef STACK_GROWS_DOWNWARDS |
128 | | guardOffset = 0; |
| 127 | guardOffset = 0; |
129 | 128 | #elif defined(STACK_GROWS_UPWARDS) |
130 | | guardOffset = virtual_size - fGuardedSize; |
| 129 | guardOffset = virtual_size - fGuardedSize; |
131 | 130 | #else |
132 | 131 | # error Stack direction has not been defined in arch_config.h |
133 | 132 | #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; |
140 | 137 | } |
| 138 | } |
141 | 139 | |
| 140 | if (fCanOvercommit) { |
142 | 141 | if (fPrecommittedPages == 0) { |
143 | 142 | // never commit more than needed |
144 | 143 | if (committed_size / B_PAGE_SIZE > page_count) |
-
diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.h b/src/system/kernel/vm/VMAnonymousNoSwapCache.h
index c9b839e..c9250ed 100644
a
|
b
|
public:
|
25 | 25 | virtual status_t Commit(off_t size, int priority); |
26 | 26 | virtual bool HasPage(off_t offset); |
27 | 27 | |
| 28 | virtual int32 GuardSize() { return fGuardedSize; } |
| 29 | |
28 | 30 | virtual status_t Read(off_t offset, const iovec* vecs, |
29 | 31 | size_t count, uint32 flags, |
30 | 32 | size_t* _numBytes); |
-
diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp
index 857bf22..af971a7 100644
a
|
b
|
map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset,
|
816 | 816 | VMCache* newCache; |
817 | 817 | |
818 | 818 | // create an anonymous cache |
819 | | bool isStack = (protection & B_STACK_AREA) != 0; |
820 | 819 | status = VMCacheFactory::CreateAnonymousCache(newCache, |
821 | | isStack || (protection & B_OVERCOMMITTING_AREA) != 0, 0, |
822 | | isStack ? USER_STACK_GUARD_PAGES : 0, true, VM_PRIORITY_USER); |
| 820 | (protection & B_STACK_AREA) != 0 |
| 821 | || (protection & B_OVERCOMMITTING_AREA) != 0, 0, |
| 822 | cache->GuardSize() / B_PAGE_SIZE, true, VM_PRIORITY_USER); |
823 | 823 | if (status != B_OK) |
824 | 824 | goto err1; |
825 | 825 | |
… |
… |
vm_reserve_address_range(team_id team, void** _address, uint32 addressSpec,
|
1177 | 1177 | |
1178 | 1178 | area_id |
1179 | 1179 | vm_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, addr_t guardSize, |
1181 | 1181 | const virtual_address_restrictions* virtualAddressRestrictions, |
1182 | 1182 | const physical_address_restrictions* physicalAddressRestrictions, |
1183 | 1183 | bool kernel, void** _address) |
… |
… |
vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
1194 | 1194 | TRACE(("create_anonymous_area [%ld] %s: size 0x%lx\n", team, name, size)); |
1195 | 1195 | |
1196 | 1196 | size = PAGE_ALIGN(size); |
| 1197 | guardSize = PAGE_ALIGN(guardSize); |
| 1198 | guardPages = guardSize / B_PAGE_SIZE; |
1197 | 1199 | |
1198 | | if (size == 0) |
| 1200 | if (size == 0 || size < guardSize) |
1199 | 1201 | return B_BAD_VALUE; |
1200 | 1202 | if (!arch_vm_supports_protection(protection)) |
1201 | 1203 | return B_NOT_SUPPORTED; |
… |
… |
vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
1371 | 1373 | |
1372 | 1374 | // create an anonymous cache |
1373 | 1375 | // 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; |
1376 | 1376 | status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit, |
1377 | 1377 | isStack ? (min_c(2, size / B_PAGE_SIZE - guardPages)) : 0, guardPages, |
1378 | 1378 | wiring == B_NO_LOCK, priority); |
… |
… |
_vm_map_file(team_id team, const char* name, void** _address,
|
1877 | 1877 | virtualRestrictions.address_specification = addressSpec; |
1878 | 1878 | physical_address_restrictions physicalRestrictions = {}; |
1879 | 1879 | return vm_create_anonymous_area(team, name, size, B_NO_LOCK, protection, |
1880 | | flags, &virtualRestrictions, &physicalRestrictions, kernel, |
| 1880 | flags, 0, &virtualRestrictions, &physicalRestrictions, kernel, |
1881 | 1881 | _address); |
1882 | 1882 | } |
1883 | 1883 | |
… |
… |
vm_copy_on_write_area(VMCache* lowerCache,
|
2302 | 2302 | |
2303 | 2303 | // create an anonymous cache |
2304 | 2304 | status_t status = VMCacheFactory::CreateAnonymousCache(upperCache, false, 0, |
2305 | | 0, dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL, |
| 2305 | lowerCache->GuardSize() / B_PAGE_SIZE, |
| 2306 | dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL, |
2306 | 2307 | VM_PRIORITY_USER); |
2307 | 2308 | if (status != B_OK) |
2308 | 2309 | return status; |
… |
… |
vm_init(kernel_args* args)
|
3887 | 3888 | create_area_etc(VMAddressSpace::KernelID(), "cache info table", |
3888 | 3889 | ROUNDUP(kCacheInfoTableCount * sizeof(cache_info), B_PAGE_SIZE), |
3889 | 3890 | B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
3890 | | CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions, |
3891 | | (void**)&sCacheInfoTable); |
| 3891 | CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, |
| 3892 | &physicalRestrictions, (void**)&sCacheInfoTable); |
3892 | 3893 | } |
3893 | 3894 | #endif // DEBUG_CACHE_LIST |
3894 | 3895 | |
… |
… |
clone_area(const char* name, void** _address, uint32 addressSpec,
|
5855 | 5856 | |
5856 | 5857 | area_id |
5857 | 5858 | create_area_etc(team_id team, const char* name, uint32 size, uint32 lock, |
5858 | | uint32 protection, uint32 flags, |
| 5859 | uint32 protection, uint32 flags, uint32 guardSize, |
5859 | 5860 | const virtual_address_restrictions* virtualAddressRestrictions, |
5860 | 5861 | const physical_address_restrictions* physicalAddressRestrictions, |
5861 | 5862 | void** _address) |
… |
… |
create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,
|
5863 | 5864 | fix_protection(&protection); |
5864 | 5865 | |
5865 | 5866 | return vm_create_anonymous_area(team, name, size, lock, protection, flags, |
5866 | | virtualAddressRestrictions, physicalAddressRestrictions, true, |
5867 | | _address); |
| 5867 | guardSize, virtualAddressRestrictions, physicalAddressRestrictions, |
| 5868 | true, _address); |
5868 | 5869 | } |
5869 | 5870 | |
5870 | 5871 | |
… |
… |
__create_area_haiku(const char* name, void** _address, uint32 addressSpec,
|
5879 | 5880 | virtualRestrictions.address_specification = addressSpec; |
5880 | 5881 | physical_address_restrictions physicalRestrictions = {}; |
5881 | 5882 | return vm_create_anonymous_area(VMAddressSpace::KernelID(), name, size, |
5882 | | lock, protection, 0, &virtualRestrictions, &physicalRestrictions, true, |
5883 | | _address); |
| 5883 | lock, protection, 0, 0, &virtualRestrictions, &physicalRestrictions, |
| 5884 | true, _address); |
5884 | 5885 | } |
5885 | 5886 | |
5886 | 5887 | |
… |
… |
_user_create_area(const char* userName, void** userAddress, uint32 addressSpec,
|
6123 | 6124 | virtualRestrictions.address_specification = addressSpec; |
6124 | 6125 | physical_address_restrictions physicalRestrictions = {}; |
6125 | 6126 | area_id area = vm_create_anonymous_area(VMAddressSpace::CurrentID(), name, |
6126 | | size, lock, protection, 0, &virtualRestrictions, &physicalRestrictions, |
6127 | | false, &address); |
| 6127 | size, lock, protection, 0, 0, &virtualRestrictions, |
| 6128 | &physicalRestrictions, false, &address); |
6128 | 6129 | |
6129 | 6130 | if (area >= B_OK |
6130 | 6131 | && user_memcpy(userAddress, &address, sizeof(address)) < B_OK) { |
-
diff --git a/src/system/libroot/posix/pthread/pthread.cpp b/src/system/libroot/posix/pthread/pthread.cpp
index 4c5104a..15c2516 100644
a
|
b
|
|
25 | 25 | static const pthread_attr pthread_attr_default = { |
26 | 26 | PTHREAD_CREATE_JOINABLE, |
27 | 27 | B_NORMAL_PRIORITY, |
28 | | USER_STACK_SIZE |
| 28 | USER_STACK_SIZE, |
| 29 | USER_STACK_GUARD_SIZE |
29 | 30 | }; |
30 | 31 | |
31 | 32 | |
… |
… |
__pthread_init_creation_attributes(const pthread_attr_t* pthreadAttributes,
|
117 | 118 | attributes->args2 = argument2; |
118 | 119 | attributes->stack_address = NULL; |
119 | 120 | attributes->stack_size = attr->stack_size; |
| 121 | attributes->guard_size = attr->guard_size; |
120 | 122 | attributes->pthread = thread; |
121 | 123 | attributes->flags = 0; |
122 | 124 | |
-
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)
|
30 | 30 | attr->detach_state = PTHREAD_CREATE_JOINABLE; |
31 | 31 | attr->sched_priority = B_NORMAL_PRIORITY; |
32 | 32 | attr->stack_size = USER_STACK_SIZE; |
| 33 | attr->guard_size = USER_STACK_GUARD_SIZE; |
33 | 34 | |
34 | 35 | *_attr = attr; |
35 | 36 | return B_OK; |
… |
… |
pthread_attr_getschedparam(const pthread_attr_t *attr,
|
162 | 163 | return 0; |
163 | 164 | } |
164 | 165 | |
| 166 | |
| 167 | int |
| 168 | pthread_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 | |
| 181 | int |
| 182 | pthread_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 | } |