about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2018-05-09 00:33:54 -0400
committerRich Felker <dalias@aerifal.cx>2018-05-09 00:37:49 -0400
commit40bae2d32fd6f3ffea437fa745ad38a1fe77b27e (patch)
treea69ba86fa80860f0248778a782c0b18a226bc0c2
parentb8742f32602add243ee2ce74d804015463726899 (diff)
downloadmusl-40bae2d32fd6f3ffea437fa745ad38a1fe77b27e.tar.gz
musl-40bae2d32fd6f3ffea437fa745ad38a1fe77b27e.tar.xz
musl-40bae2d32fd6f3ffea437fa745ad38a1fe77b27e.zip
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.
-rw-r--r--src/internal/pthread_impl.h8
-rw-r--r--src/thread/pthread_attr_setinheritsched.c21
-rw-r--r--src/thread/pthread_create.c35
3 files changed, 36 insertions, 28 deletions
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
index 69352ef2..c2deffb9 100644
--- a/src/internal/pthread_impl.h
+++ b/src/internal/pthread_impl.h
@@ -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,
diff --git a/src/thread/pthread_attr_setinheritsched.c b/src/thread/pthread_attr_setinheritsched.c
index c91d8f83..e540e846 100644
--- a/src/thread/pthread_attr_setinheritsched.c
+++ b/src/thread/pthread_attr_setinheritsched.c
@@ -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)
 {
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index 5f07ab49..2c066cff 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -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);
 	}