فهرست منبع

pthread and synccall cleanup, new __synccall_wait op

fix up clone signature to match the actual behavior. the new
__syncall_wait function allows a __synccall callback to wait for other
threads to continue without returning, so that it can resume action
after the caller finishes. this interface could be made significantly
more general/powerful with minimal effort, but i'll wait to do that
until it's actually useful for something.
Rich Felker 13 سال پیش
والد
کامیت
407d933052
4فایلهای تغییر یافته به همراه13 افزوده شده و 7 حذف شده
  1. 1 0
      src/internal/libc.h
  2. 1 0
      src/internal/pthread_impl.h
  3. 1 5
      src/thread/pthread_create.c
  4. 10 2
      src/thread/synccall.c

+ 1 - 0
src/internal/libc.h

@@ -41,6 +41,7 @@ void __unlockfile(FILE *);
 #define UNLOCK(x) (*(volatile int *)(x)=0)
 
 void __synccall(void (*)(void *), void *);
+void __synccall_wait(void);
 int __setxid(int, int, int, int);
 
 extern char **__environ;

+ 1 - 0
src/internal/pthread_impl.h

@@ -87,6 +87,7 @@ struct __timer {
 
 pthread_t __pthread_self_init(void);
 
+int __uniclone(void *, void (*)(pthread_t), void *);
 int __set_thread_area(void *);
 int __libc_sigaction(int, const struct sigaction *, struct sigaction *);
 int __libc_sigprocmask(int, const sigset_t *, sigset_t *);

+ 1 - 5
src/thread/pthread_create.c

@@ -52,17 +52,13 @@ void __pthread_do_unregister(struct __ptcb *cb)
 	self->cancelbuf = self->cancelbuf->__next;
 }
 
-static int start(void *p)
+static void start(pthread_t self)
 {
-	struct pthread *self = p;
 	if (self->unblock_cancel)
 		__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, 8);
 	pthread_exit(self->start(self->start_arg));
-	return 0;
 }
 
-int __uniclone(void *, int (*)(), void *);
-
 #define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE)
 
 /* pthread_key_create.c overrides this */

+ 10 - 2
src/thread/synccall.c

@@ -4,7 +4,7 @@
 static struct chain {
 	struct chain *next;
 	sem_t sem, sem2;
-} *head;
+} *head, *cur;
 
 static void (*callback)(void *), *context;
 static int chainlen;
@@ -47,11 +47,19 @@ static void handler(int sig, siginfo_t *si, void *ctx)
 	errno = old_errno;
 }
 
+void __synccall_wait()
+{
+	struct chain *ch = cur;
+	sem_post(&ch->sem2);
+	while (sem_wait(&ch->sem));
+	sem_post(&ch->sem);
+}
+
 void __synccall(void (*func)(void *), void *ctx)
 {
 	pthread_t self;
 	struct sigaction sa;
-	struct chain *cur, *next;
+	struct chain *next;
 	uint64_t oldmask;
 
 	if (!libc.threads_minus_1) {