make linking of thread-start with explicit scheduling conditional

the wrapper start function that performs scheduling operations is
unreachable if pthread_attr_setinheritsched is never called, so move
it there rather than the pthread_create source file, saving some code
size for static-linked programs.
This commit is contained in:
Rich Felker 2018-05-09 00:33:54 -04:00
parent b8742f3260
commit 40bae2d32f
3 changed files with 36 additions and 28 deletions

View File

@ -56,6 +56,14 @@ struct pthread {
void **dtv_copy;
};
struct start_sched_args {
void *start_arg;
void *(*start_fn)(void *);
sigset_t mask;
pthread_attr_t *attr;
volatile int futex;
};
enum {
DT_EXITED = 0,
DT_EXITING,

View File

@ -1,4 +1,25 @@
#include "pthread_impl.h"
#include "syscall.h"
__attribute__((__visibility__("hidden")))
void *__start_sched(void *p)
{
struct start_sched_args *ssa = p;
void *start_arg = ssa->start_arg;
void *(*start_fn)(void *) = ssa->start_fn;
pthread_t self = __pthread_self();
int ret = -__syscall(SYS_sched_setscheduler, self->tid,
ssa->attr->_a_policy, &ssa->attr->_a_prio);
if (!ret) __restore_sigs(&ssa->mask);
a_store(&ssa->futex, ret);
__wake(&ssa->futex, 1, 1);
if (ret) {
self->detach_state = DT_DYNAMIC;
return 0;
}
return start_fn(start_arg);
}
int pthread_attr_setinheritsched(pthread_attr_t *a, int inherit)
{

View File

@ -19,6 +19,12 @@ weak_alias(dummy_0, __pthread_tsd_run_dtors);
weak_alias(dummy_0, __do_orphaned_stdio_locks);
weak_alias(dummy_0, __dl_thread_cleanup);
static void *dummy_1(void *p)
{
return 0;
}
weak_alias(dummy_1, __start_sched);
_Noreturn void __pthread_exit(void *result)
{
pthread_t self = __pthread_self();
@ -132,33 +138,6 @@ void __do_cleanup_pop(struct __ptcb *cb)
__pthread_self()->cancelbuf = cb->__next;
}
struct start_sched_args {
void *start_arg;
void *(*start_fn)(void *);
sigset_t mask;
pthread_attr_t *attr;
volatile int futex;
};
static void *start_sched(void *p)
{
struct start_sched_args *ssa = p;
void *start_arg = ssa->start_arg;
void *(*start_fn)(void *) = ssa->start_fn;
pthread_t self = __pthread_self();
int ret = -__syscall(SYS_sched_setscheduler, self->tid,
ssa->attr->_a_policy, &ssa->attr->_a_prio);
if (!ret) __restore_sigs(&ssa->mask);
a_store(&ssa->futex, ret);
__wake(&ssa->futex, 1, 1);
if (ret) {
self->detach_state = DT_DYNAMIC;
return 0;
}
return start_fn(start_arg);
}
static int start(void *p)
{
pthread_t self = p;
@ -302,7 +281,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
ssa.start_fn = new->start;
ssa.start_arg = new->start_arg;
ssa.attr = &attr;
new->start = start_sched;
new->start = __start_sched;
new->start_arg = &ssa;
__block_app_sigs(&ssa.mask);
}