diff options
author | Rich Felker <dalias@aerifal.cx> | 2012-06-09 19:53:29 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2012-06-09 19:53:29 -0400 |
commit | 819006a88b9473872fee91135b06f4e23231d97e (patch) | |
tree | a123767e77980a5feeee0e05a21ea2fe2b2a2b8e /src/thread/pthread_create.c | |
parent | f457b1cb0d49f1b47bc7baf4bb516f1860816f03 (diff) | |
download | musl-819006a88b9473872fee91135b06f4e23231d97e.tar.gz musl-819006a88b9473872fee91135b06f4e23231d97e.tar.xz musl-819006a88b9473872fee91135b06f4e23231d97e.zip |
add pthread_attr_setstack interface (and get)
i originally omitted these (optional, per POSIX) interfaces because i considered them backwards implementation details. however, someone later brought to my attention a fairly legitimate use case: allocating thread stacks in memory that's setup for sharing and/or fast transfer between CPU and GPU so that the thread can move data to a GPU directly from automatic-storage buffers without having to go through additional buffer copies. perhaps there are other situations in which these interfaces are useful too.
Diffstat (limited to 'src/thread/pthread_create.c')
-rw-r--r-- | src/thread/pthread_create.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 5b34e7e8..48290d35 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -98,16 +98,20 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo libc.threaded = 1; } - if (attr) { - guard = ROUND(attr->_a_guardsize + DEFAULT_GUARD_SIZE); - size = guard + ROUND(attr->_a_stacksize + DEFAULT_STACK_SIZE); + if (attr && attr->_a_stackaddr) { + map = 0; + tsd = (void *)(attr->_a_stackaddr-__pthread_tsd_size & -16); + } else { + if (attr) { + guard = ROUND(attr->_a_guardsize + DEFAULT_GUARD_SIZE); + size = guard + ROUND(attr->_a_stacksize + DEFAULT_STACK_SIZE); + } + size += __pthread_tsd_size; + map = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); + if (map == MAP_FAILED) return EAGAIN; + if (guard) mprotect(map, guard, PROT_NONE); + tsd = map + size - __pthread_tsd_size; } - size += __pthread_tsd_size; - map = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); - if (map == MAP_FAILED) return EAGAIN; - if (guard) mprotect(map, guard, PROT_NONE); - - tsd = map + size - __pthread_tsd_size; new = (void *)(tsd - sizeof *new - PAGE_SIZE%sizeof *new); new->map_base = map; new->map_size = size; |