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.
This commit is contained in:
Hamish Morrison
2012-12-28 18:02:58 +00:00
parent 00e7904406
commit d1f280c805
29 changed files with 148 additions and 87 deletions
+4 -5
View File
@@ -185,6 +185,10 @@ extern int pthread_attr_getschedparam(const pthread_attr_t *attr,
extern int pthread_attr_setschedparam(pthread_attr_t *attr,
const struct sched_param *param);
extern int pthread_attr_getguardsize(const pthread_attr_t *attr,
size_t *guardsize);
extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
#if 0 /* Unimplemented attribute functions: */
/* [TPS] */
@@ -196,11 +200,6 @@ extern int pthread_attr_getschedpolicy(const pthread_attr_t *attr,
int *policy);
extern int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
/* [XSI] */
extern int pthread_attr_getguardsize(const pthread_attr_t *attr,
size_t *guardsize);
extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
/* [TSA] */
extern int pthread_attr_getstackaddr(const pthread_attr_t *attr,
void **stackaddr);
+2
View File
@@ -117,6 +117,8 @@ public:
inline void IncrementWiredPagesCount();
inline void DecrementWiredPagesCount();
virtual int32 GuardSize() { return 0; }
void AddConsumer(VMCache* consumer);
status_t InsertAreaLocked(VMArea* area);
+2 -2
View File
@@ -77,7 +77,7 @@ void forbid_page_faults(void);
// private kernel only extension (should be moved somewhere else):
area_id create_area_etc(team_id team, const char *name, uint32 size,
uint32 lock, uint32 protection, uint32 flags,
uint32 lock, uint32 protection, uint32 flags, uint32 guardSize,
const virtual_address_restrictions* virtualAddressRestrictions,
const physical_address_restrictions* physicalAddressRestrictions,
void **_address);
@@ -95,7 +95,7 @@ status_t vm_unreserve_address_range(team_id team, void *address, addr_t size);
status_t vm_reserve_address_range(team_id team, void **_address,
uint32 addressSpec, addr_t size, uint32 flags);
area_id vm_create_anonymous_area(team_id team, const char* name, addr_t size,
uint32 wiring, uint32 protection, uint32 flags,
uint32 wiring, uint32 protection, uint32 flags, addr_t guardSize,
const virtual_address_restrictions* virtualAddressRestrictions,
const physical_address_restrictions* physicalAddressRestrictions,
bool kernel, void** _address);
@@ -40,6 +40,7 @@ typedef struct _pthread_attr {
int32 detach_state;
int32 sched_priority;
size_t stack_size;
size_t guard_size;
} pthread_attr;
typedef struct _pthread_rwlockattr {
+6 -8
View File
@@ -12,14 +12,11 @@
/** Size of the stack given to teams in user space */
#define USER_STACK_GUARD_PAGES 4 // 16 kB
#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024 \
- USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 16 MB
#define USER_STACK_SIZE (256 * 1024 \
- USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 256 kB
#define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB
#define MAX_USER_STACK_SIZE (16 * 1024 * 1024 \
- USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 16 MB
#define USER_STACK_GUARD_SIZE (4 * B_PAGE_SIZE) // 16 kB
#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB
#define USER_STACK_SIZE (256 * 1024) // 256 kB
#define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB
#define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB
// The type of object a thread blocks on (thread::wait::type, set by
@@ -50,6 +47,7 @@ struct thread_creation_attributes {
void* args2;
void* stack_address;
size_t stack_size;
size_t guard_size;
pthread_t pthread;
uint32 flags;
};
@@ -195,7 +195,7 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)
// TODO: Use 64 bit addresses, if possible!
#endif
buffer->area = create_area_etc(B_SYSTEM_TEAM, "DMA buffer", size,
B_CONTIGUOUS, 0, 0, &virtualRestrictions, &physicalRestrictions,
B_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, &physicalRestrictions,
(void**)&buffer->address);
if (buffer->area < 0) {
@@ -74,7 +74,7 @@ scsi_init_emulation_buffer(scsi_device_info *device, size_t buffer_size)
physical_address_restrictions physicalRestrictions = {};
physicalRestrictions.alignment = buffer_size;
device->buffer_area = create_area_etc(B_SYSTEM_TEAM, "ATAPI buffer",
total_size, B_32_BIT_CONTIGUOUS, 0, 0, &virtualRestrictions,
total_size, B_32_BIT_CONTIGUOUS, 0, 0, 0, &virtualRestrictions,
&physicalRestrictions, &address);
// TODO: Use B_CONTIGUOUS, if possible!
@@ -37,7 +37,7 @@ _kernel_contigmalloc_cpp(const char* file, int line, size_t size,
void* address;
area_id area = create_area_etc(B_SYSTEM_TEAM, name, size, B_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, 0,
&virtualRestrictions, &physicalRestrictions, &address);
if (area < 0)
return NULL;
@@ -73,3 +73,17 @@ WRAPPER_FUNCTION(int, pthread_attr_getschedparam,
return B_TO_POSITIVE_ERROR(sReal_pthread_attr_getschedparam(attr,
param));
)
WRAPPER_FUNCTION(int, pthread_attr_getguardsize,
(const pthread_attr_t *attr, size_t *guardsize),
return B_TO_POSITIVE_ERROR(sReal_pthread_attr_getguardsize(attr,
guardsize));
)
WRAPPER_FUNCTION(int, pthread_attr_setguardsize,
(pthread_attr_t *attr, size_t guardsize),
return B_TO_POSITIVE_ERROR(sReal_pthread_attr_setguardsize(attr,
guardsize));
)
@@ -197,7 +197,7 @@ ARMPagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(
physical_address_restrictions physicalRestrictions = {};
area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
PAGE_ALIGN(areaSize), B_FULL_LOCK,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
&virtualRestrictions, &physicalRestrictions, &data);
if (dataArea < 0)
return dataArea;
@@ -552,7 +552,7 @@ x86_descriptors_init_post_vm(kernel_args* args)
physical_address_restrictions physicalRestrictions = {};
area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
&virtualRestrictions, &physicalRestrictions, (void**)&idt);
0, &virtualRestrictions, &physicalRestrictions, (void**)&idt);
if (area < 0)
return area;
+1 -1
View File
@@ -792,7 +792,7 @@ arch_cpu_init_post_vm(kernel_args* args)
physical_address_restrictions physicalRestrictions = {};
create_area_etc(B_SYSTEM_TEAM, "double fault stacks",
kDoubleFaultStackSize * smp_get_num_cpus(), B_FULL_LOCK,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
&virtualRestrictions, &physicalRestrictions,
(void**)&sDoubleFaultStacks);
@@ -195,7 +195,7 @@ X86PagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(
physical_address_restrictions physicalRestrictions = {};
area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
PAGE_ALIGN(areaSize), B_FULL_LOCK,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
&virtualRestrictions, &physicalRestrictions, &data);
if (dataArea < 0)
return dataArea;
@@ -487,7 +487,7 @@ X86PagingMethodPAE::PhysicalPageSlotPool::AllocatePool(
physical_address_restrictions physicalRestrictions = {};
area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
PAGE_ALIGN(areaSize), B_FULL_LOCK,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
&virtualRestrictions, &physicalRestrictions, &data);
if (dataArea < 0)
return dataArea;
+1 -1
View File
@@ -309,7 +309,7 @@ debug_heap_init()
physical_address_restrictions physicalRestrictions = {};
area_id area = create_area_etc(B_SYSTEM_TEAM, "kdebug heap", KDEBUG_HEAP,
B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions,
CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, &physicalRestrictions,
(void**)&base);
if (area < 0)
return;
+4 -4
View File
@@ -452,7 +452,7 @@ TracingMetaData::Create(TracingMetaData*& _metaData)
physical_address_restrictions physicalRestrictions = {};
area = create_area_etc(B_SYSTEM_TEAM, "tracing log",
kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
&virtualRestrictions, &physicalRestrictions,
(void**)&metaData->fTraceOutputBuffer);
if (area < 0)
@@ -503,8 +503,8 @@ TracingMetaData::_CreateMetaDataArea(bool findPrevious, area_id& _area,
physicalRestrictions.high_address = metaDataAddress + B_PAGE_SIZE;
area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing metadata",
B_PAGE_SIZE, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
CREATE_AREA_DONT_CLEAR, &virtualRestrictions, &physicalRestrictions,
(void**)&metaData);
CREATE_AREA_DONT_CLEAR, 0, &virtualRestrictions,
&physicalRestrictions, (void**)&metaData);
if (area < 0)
continue;
@@ -567,7 +567,7 @@ TracingMetaData::_InitPreviousTracingData()
+ ROUNDUP(kTraceOutputBufferSize + MAX_TRACE_SIZE, B_PAGE_SIZE);
area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing log",
kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR, 0,
&virtualRestrictions, &physicalRestrictions, NULL);
if (area < 0) {
dprintf("Failed to init tracing meta data: Mapping tracing log "
@@ -246,7 +246,7 @@ DMAResource::CreateBounceBuffer(DMABounceBuffer** _buffer)
physicalRestrictions.alignment = fRestrictions.alignment;
physicalRestrictions.boundary = fRestrictions.boundary;
area = create_area_etc(B_SYSTEM_TEAM, "dma buffer", size, B_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, &virtualRestrictions,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, 0, &virtualRestrictions,
&physicalRestrictions, &bounceBuffer);
if (area < B_OK)
return area;
+1 -1
View File
@@ -1943,7 +1943,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
virtualRestrictions.address_specification = B_EXACT_ADDRESS;
physical_address_restrictions physicalRestrictions = {};
id = create_area_etc(team->id, regionName, bssSize, B_NO_LOCK,
B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
&physicalRestrictions, (void**)&regionAddress);
if (id < B_OK) {
dprintf("error allocating bss area: %s!\n", strerror(id));
+1 -1
View File
@@ -432,7 +432,7 @@ haiku_sem_init(kernel_args *args)
physical_address_restrictions physicalRestrictions = {};
area = create_area_etc(B_SYSTEM_TEAM, "sem_table",
sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
&virtualRestrictions, &physicalRestrictions, (void**)&sSems);
if (area < 0)
panic("unable to allocate semaphore table!\n");
+1 -1
View File
@@ -627,7 +627,7 @@ MemoryManager::AllocateRaw(size_t size, uint32 flags, void*& _pages)
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
((flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0
? CREATE_AREA_DONT_WAIT : 0)
| CREATE_AREA_DONT_CLEAR,
| CREATE_AREA_DONT_CLEAR, 0,
&virtualRestrictions, &physicalRestrictions, &_pages);
status_t result = area >= 0 ? B_OK : area;
+1 -1
View File
@@ -1333,7 +1333,7 @@ create_team_user_data(Team* team)
virtualRestrictions.address_specification = B_BASE_ADDRESS;
physical_address_restrictions physicalRestrictions = {};
team->user_data_area = create_area_etc(team->id, "user area", size,
B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
&physicalRestrictions, &address);
if (team->user_data_area < 0)
return team->user_data_area;
+27 -13
View File
@@ -524,6 +524,7 @@ ThreadCreationAttributes::ThreadCreationAttributes(thread_func function,
this->args2 = NULL;
this->stack_address = NULL;
this->stack_size = 0;
this->guard_size = 0;
this->pthread = NULL;
this->flags = 0;
this->team = team >= 0 ? team : team_get_kernel_team()->id;
@@ -781,14 +782,15 @@ init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)
static status_t
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
size_t stackSize, size_t additionalSize, char* nameBuffer)
size_t stackSize, size_t additionalSize, size_t guardSize,
char* nameBuffer)
{
area_id stackArea = -1;
uint8* stackBase = (uint8*)_stackBase;
if (stackBase != NULL) {
// A stack has been specified. It must be large enough to hold the
// TLS space at least.
// TLS space at least. Guard pages are ignored for existing stacks.
STATIC_ASSERT(TLS_SIZE < MIN_USER_STACK_SIZE);
if (stackSize < MIN_USER_STACK_SIZE)
return B_BAD_VALUE;
@@ -799,20 +801,22 @@ create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
// will be between USER_STACK_REGION and the main thread stack area. For
// a main thread the position is fixed.
guardSize = PAGE_ALIGN(guardSize);
if (stackSize == 0) {
// Use the default size (a different one for a main thread).
stackSize = thread->id == team->id
? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE;
} else {
// Verify that the given stack size is large enough.
if (stackSize < MIN_USER_STACK_SIZE - TLS_SIZE)
if (stackSize < MIN_USER_STACK_SIZE)
return B_BAD_VALUE;
stackSize = PAGE_ALIGN(stackSize);
}
stackSize += USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + additionalSize);
size_t areaSize = PAGE_ALIGN(guardSize + stackSize + TLS_SIZE
+ additionalSize);
snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_stack",
thread->name, thread->id);
@@ -836,7 +840,7 @@ create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
stackArea = create_area_etc(team->id, nameBuffer,
areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA,
0, &virtualRestrictions, &physicalRestrictions,
0, guardSize, &virtualRestrictions, &physicalRestrictions,
(void**)&stackBase);
if (stackArea < 0)
return stackArea;
@@ -844,7 +848,11 @@ create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
// set the stack
ThreadLocker threadLocker(thread);
#ifdef STACK_GROWS_DOWNWARDS
thread->user_stack_base = (addr_t)stackBase + guardSize;
#else
thread->user_stack_base = (addr_t)stackBase;
#endif
thread->user_stack_size = stackSize;
thread->user_stack_area = stackArea;
@@ -858,7 +866,7 @@ thread_create_user_stack(Team* team, Thread* thread, void* stackBase,
{
char nameBuffer[B_OS_NAME_LENGTH];
return create_thread_user_stack(team, thread, stackBase, stackSize,
additionalSize, nameBuffer);
additionalSize, USER_STACK_GUARD_SIZE, nameBuffer);
}
@@ -915,11 +923,16 @@ thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
char stackName[B_OS_NAME_LENGTH];
snprintf(stackName, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_kstack",
thread->name, thread->id);
thread->kernel_stack_area = create_area(stackName,
(void **)&thread->kernel_stack_base, B_ANY_KERNEL_ADDRESS,
KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
B_FULL_LOCK,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA);
virtual_address_restrictions virtualRestrictions = {};
virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS;
physical_address_restrictions physicalRestrictions = {};
thread->kernel_stack_area = create_area_etc(B_SYSTEM_TEAM, stackName,
KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA
| B_KERNEL_STACK_AREA, 0, KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
&virtualRestrictions, &physicalRestrictions,
(void**)&thread->kernel_stack_base);
if (thread->kernel_stack_area < 0) {
// we're not yet part of a team, so we can just bail out
@@ -948,7 +961,8 @@ thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
if (thread->user_stack_base == 0) {
status = create_thread_user_stack(team, thread,
attributes.stack_address, attributes.stack_size,
attributes.additional_stack_size, stackName);
attributes.additional_stack_size, attributes.guard_size,
stackName);
if (status != B_OK)
return status;
}
+10 -11
View File
@@ -787,25 +787,24 @@ VMAnonymousCache::MaxPagesPerAsyncWrite() const
status_t
VMAnonymousCache::Fault(struct VMAddressSpace* aspace, off_t offset)
{
if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) {
if (fGuardedSize > 0) {
uint32 guardOffset;
if (fGuardedSize > 0) {
uint32 guardOffset;
#ifdef STACK_GROWS_DOWNWARDS
guardOffset = 0;
guardOffset = 0;
#elif defined(STACK_GROWS_UPWARDS)
guardOffset = virtual_size - fGuardedSize;
guardOffset = virtual_size - fGuardedSize;
#else
# error Stack direction has not been defined in arch_config.h
#endif
// report stack fault, guard page hit!
if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
TRACE(("stack overflow!\n"));
return B_BAD_ADDRESS;
}
// report stack fault, guard page hit!
if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
TRACE(("stack overflow!\n"));
return B_BAD_ADDRESS;
}
}
if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) {
if (fPrecommittedPages == 0) {
// never commit more than needed
if (committed_size / B_PAGE_SIZE > page_count)
+2
View File
@@ -45,6 +45,8 @@ public:
virtual bool HasPage(off_t offset);
virtual bool DebugHasPage(off_t offset);
virtual int32 GuardSize() { return fGuardedSize; }
virtual status_t Read(off_t offset, const generic_io_vec* vecs,
size_t count, uint32 flags,
generic_size_t* _numBytes);
+10 -11
View File
@@ -120,25 +120,24 @@ VMAnonymousNoSwapCache::Write(off_t offset, const iovec* vecs, size_t count,
status_t
VMAnonymousNoSwapCache::Fault(struct VMAddressSpace* aspace, off_t offset)
{
if (fCanOvercommit) {
if (fGuardedSize > 0) {
uint32 guardOffset;
if (fGuardedSize > 0) {
uint32 guardOffset;
#ifdef STACK_GROWS_DOWNWARDS
guardOffset = 0;
guardOffset = 0;
#elif defined(STACK_GROWS_UPWARDS)
guardOffset = virtual_size - fGuardedSize;
guardOffset = virtual_size - fGuardedSize;
#else
# error Stack direction has not been defined in arch_config.h
#endif
// report stack fault, guard page hit!
if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
TRACE(("stack overflow!\n"));
return B_BAD_ADDRESS;
}
// report stack fault, guard page hit!
if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
TRACE(("stack overflow!\n"));
return B_BAD_ADDRESS;
}
}
if (fCanOvercommit) {
if (fPrecommittedPages == 0) {
// never commit more than needed
if (committed_size / B_PAGE_SIZE > page_count)
@@ -25,6 +25,8 @@ public:
virtual status_t Commit(off_t size, int priority);
virtual bool HasPage(off_t offset);
virtual int32 GuardSize() { return fGuardedSize; }
virtual status_t Read(off_t offset, const iovec* vecs,
size_t count, uint32 flags,
size_t* _numBytes);
+19 -18
View File
@@ -817,10 +817,10 @@ map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset,
VMCache* newCache;
// create an anonymous cache
bool isStack = (protection & B_STACK_AREA) != 0;
status = VMCacheFactory::CreateAnonymousCache(newCache,
isStack || (protection & B_OVERCOMMITTING_AREA) != 0, 0,
isStack ? USER_STACK_GUARD_PAGES : 0, true, VM_PRIORITY_USER);
(protection & B_STACK_AREA) != 0
|| (protection & B_OVERCOMMITTING_AREA) != 0, 0,
cache->GuardSize() / B_PAGE_SIZE, true, VM_PRIORITY_USER);
if (status != B_OK)
goto err1;
@@ -1178,7 +1178,7 @@ vm_reserve_address_range(team_id team, void** _address, uint32 addressSpec,
area_id
vm_create_anonymous_area(team_id team, const char *name, addr_t size,
uint32 wiring, uint32 protection, uint32 flags,
uint32 wiring, uint32 protection, uint32 flags, addr_t guardSize,
const virtual_address_restrictions* virtualAddressRestrictions,
const physical_address_restrictions* physicalAddressRestrictions,
bool kernel, void** _address)
@@ -1196,8 +1196,10 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size,
team, name, size));
size = PAGE_ALIGN(size);
guardSize = PAGE_ALIGN(guardSize);
guardPages = guardSize / B_PAGE_SIZE;
if (size == 0)
if (size == 0 || size < guardSize)
return B_BAD_VALUE;
if (!arch_vm_supports_protection(protection))
return B_NOT_SUPPORTED;
@@ -1373,8 +1375,6 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size,
// create an anonymous cache
// if it's a stack, make sure that two pages are available at least
guardPages = isStack ? ((protection & B_USER_PROTECTION) != 0
? USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0;
status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit,
isStack ? (min_c(2, size / B_PAGE_SIZE - guardPages)) : 0, guardPages,
wiring == B_NO_LOCK, priority);
@@ -1879,7 +1879,7 @@ _vm_map_file(team_id team, const char* name, void** _address,
virtualRestrictions.address_specification = addressSpec;
physical_address_restrictions physicalRestrictions = {};
return vm_create_anonymous_area(team, name, size, B_NO_LOCK, protection,
flags, &virtualRestrictions, &physicalRestrictions, kernel,
flags, 0, &virtualRestrictions, &physicalRestrictions, kernel,
_address);
}
@@ -2305,7 +2305,8 @@ vm_copy_on_write_area(VMCache* lowerCache,
// create an anonymous cache
status_t status = VMCacheFactory::CreateAnonymousCache(upperCache, false, 0,
0, dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL,
lowerCache->GuardSize() / B_PAGE_SIZE,
dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL,
VM_PRIORITY_USER);
if (status != B_OK)
return status;
@@ -3893,8 +3894,8 @@ vm_init(kernel_args* args)
create_area_etc(VMAddressSpace::KernelID(), "cache info table",
ROUNDUP(kCacheInfoTableCount * sizeof(cache_info), B_PAGE_SIZE),
B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions,
(void**)&sCacheInfoTable);
CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions,
&physicalRestrictions, (void**)&sCacheInfoTable);
}
#endif // DEBUG_CACHE_LIST
@@ -5863,7 +5864,7 @@ clone_area(const char* name, void** _address, uint32 addressSpec,
area_id
create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,
uint32 protection, uint32 flags,
uint32 protection, uint32 flags, uint32 guardSize,
const virtual_address_restrictions* virtualAddressRestrictions,
const physical_address_restrictions* physicalAddressRestrictions,
void** _address)
@@ -5871,8 +5872,8 @@ create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,
fix_protection(&protection);
return vm_create_anonymous_area(team, name, size, lock, protection, flags,
virtualAddressRestrictions, physicalAddressRestrictions, true,
_address);
guardSize, virtualAddressRestrictions, physicalAddressRestrictions,
true, _address);
}
@@ -5887,8 +5888,8 @@ __create_area_haiku(const char* name, void** _address, uint32 addressSpec,
virtualRestrictions.address_specification = addressSpec;
physical_address_restrictions physicalRestrictions = {};
return vm_create_anonymous_area(VMAddressSpace::KernelID(), name, size,
lock, protection, 0, &virtualRestrictions, &physicalRestrictions, true,
_address);
lock, protection, 0, 0, &virtualRestrictions, &physicalRestrictions,
true, _address);
}
@@ -6131,8 +6132,8 @@ _user_create_area(const char* userName, void** userAddress, uint32 addressSpec,
virtualRestrictions.address_specification = addressSpec;
physical_address_restrictions physicalRestrictions = {};
area_id area = vm_create_anonymous_area(VMAddressSpace::CurrentID(), name,
size, lock, protection, 0, &virtualRestrictions, &physicalRestrictions,
false, &address);
size, lock, protection, 0, 0, &virtualRestrictions,
&physicalRestrictions, false, &address);
if (area >= B_OK
&& user_memcpy(userAddress, &address, sizeof(address)) < B_OK) {
+3 -1
View File
@@ -25,7 +25,8 @@
static const pthread_attr pthread_attr_default = {
PTHREAD_CREATE_JOINABLE,
B_NORMAL_PRIORITY,
USER_STACK_SIZE
USER_STACK_SIZE,
USER_STACK_GUARD_SIZE
};
@@ -117,6 +118,7 @@ __pthread_init_creation_attributes(const pthread_attr_t* pthreadAttributes,
attributes->args2 = argument2;
attributes->stack_address = NULL;
attributes->stack_size = attr->stack_size;
attributes->guard_size = attr->guard_size;
attributes->pthread = thread;
attributes->flags = 0;
@@ -30,6 +30,7 @@ pthread_attr_init(pthread_attr_t *_attr)
attr->detach_state = PTHREAD_CREATE_JOINABLE;
attr->sched_priority = B_NORMAL_PRIORITY;
attr->stack_size = USER_STACK_SIZE;
attr->guard_size = USER_STACK_GUARD_SIZE;
*_attr = attr;
return B_OK;
@@ -162,3 +163,30 @@ pthread_attr_getschedparam(const pthread_attr_t *attr,
return 0;
}
int
pthread_attr_getguardsize(const pthread_attr_t *_attr, size_t *guardsize)
{
pthread_attr *attr;
if (_attr == NULL || (attr = *_attr) == NULL || guardsize == NULL)
return B_BAD_VALUE;
*guardsize = attr->guard_size;
return 0;
}
int
pthread_attr_setguardsize(pthread_attr_t *_attr, size_t guardsize)
{
pthread_attr *attr;
if (_attr == NULL || (attr = *_attr) == NULL)
return B_BAD_VALUE;
attr->guard_size = guardsize;
return 0;
}