提交 819006a8 编写于 作者: R Rich Felker

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.
上级 f457b1cb
...@@ -59,7 +59,8 @@ struct __timer { ...@@ -59,7 +59,8 @@ struct __timer {
#define _a_stacksize __u.__s[0] #define _a_stacksize __u.__s[0]
#define _a_guardsize __u.__s[1] #define _a_guardsize __u.__s[1]
#define _a_detach __u.__i[2*__SU+0] #define _a_stackaddr __u.__s[2]
#define _a_detach __u.__i[3*__SU+0]
#define _m_type __u.__i[0] #define _m_type __u.__i[0]
#define _m_lock __u.__i[1] #define _m_lock __u.__i[1]
#define _m_waiters __u.__i[2] #define _m_waiters __u.__i[2]
......
#include "pthread_impl.h"
int pthread_attr_getstack(const pthread_attr_t *a, void **addr, size_t *size)
{
if (!a->_a_stackaddr)
return EINVAL;
*size = a->_a_stacksize + DEFAULT_STACK_SIZE;
*addr = (void *)(a->_a_stackaddr - *size);
return 0;
}
#include "pthread_impl.h"
/* pthread_key_create.c overrides this */
static const size_t dummy = 0;
weak_alias(dummy, __pthread_tsd_size);
int pthread_attr_setstack(pthread_attr_t *a, void *addr, size_t size)
{
if (size-PTHREAD_STACK_MIN-__pthread_tsd_size > SIZE_MAX/4)
return EINVAL;
a->_a_stackaddr = (size_t)addr + size;
a->_a_stacksize = size - DEFAULT_STACK_SIZE;
return 0;
}
...@@ -98,6 +98,10 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo ...@@ -98,6 +98,10 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo
libc.threaded = 1; libc.threaded = 1;
} }
if (attr && attr->_a_stackaddr) {
map = 0;
tsd = (void *)(attr->_a_stackaddr-__pthread_tsd_size & -16);
} else {
if (attr) { if (attr) {
guard = ROUND(attr->_a_guardsize + DEFAULT_GUARD_SIZE); guard = ROUND(attr->_a_guardsize + DEFAULT_GUARD_SIZE);
size = guard + ROUND(attr->_a_stacksize + DEFAULT_STACK_SIZE); size = guard + ROUND(attr->_a_stacksize + DEFAULT_STACK_SIZE);
...@@ -106,8 +110,8 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo ...@@ -106,8 +110,8 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo
map = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); map = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
if (map == MAP_FAILED) return EAGAIN; if (map == MAP_FAILED) return EAGAIN;
if (guard) mprotect(map, guard, PROT_NONE); if (guard) mprotect(map, guard, PROT_NONE);
tsd = map + size - __pthread_tsd_size; tsd = map + size - __pthread_tsd_size;
}
new = (void *)(tsd - sizeof *new - PAGE_SIZE%sizeof *new); new = (void *)(tsd - sizeof *new - PAGE_SIZE%sizeof *new);
new->map_base = map; new->map_base = map;
new->map_size = size; new->map_size = size;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册