From 291f1cd8c30897cd55b75c4570a43965daaf4240 Mon Sep 17 00:00:00 2001 From: Lionel Sambuc Date: Sun, 21 Jan 2018 09:59:02 +0100 Subject: [PATCH] pthreads wip --- lib/libc/gen/gr_private.h | 2 +- lib/libc/gen/syslog.c | 35 +++++++++++++------------ lib/libpthread/pthread.c | 6 +++++ lib/libpthread/pthread_userspace.c | 34 +++++++++++++++---------- minix/lib/libc/sys/_minix_lwp.c | 41 ++++++++++++++++++++++-------- 5 files changed, 74 insertions(+), 44 deletions(-) diff --git a/lib/libc/gen/gr_private.h b/lib/libc/gen/gr_private.h index 2532a1754..5482389d3 100644 --- a/lib/libc/gen/gr_private.h +++ b/lib/libc/gen/gr_private.h @@ -46,7 +46,7 @@ * back-end implementations, which may not be reentrant. */ extern mutex_t __grmutex; -#endif /* defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ /* * files methods diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c index 5ece67ddd..85f11ad28 100644 --- a/lib/libc/gen/syslog.c +++ b/lib/libc/gen/syslog.c @@ -294,10 +294,10 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid, #endif } -#if !defined(__minix) +#if defined(__minix) && defined(_REENTRANT) if (data == &sdata) mutex_lock(&syslog_mutex); -#endif /* !defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ if (data->log_hostname[0] == '\0' && gethostname(data->log_hostname, sizeof(data->log_hostname)) == -1) { @@ -316,10 +316,10 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid, prlen = snprintf_ss(p, tbuf_left, "%s ", data->log_tag ? data->log_tag : "-"); -#if !defined(__minix) +#if defined(__minix) && defined(_REENTRANT) if (data == &sdata) mutex_unlock(&syslog_mutex); -#endif /* !defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ if (data->log_stat & (LOG_PERROR|LOG_CONS)) { iovcnt = 0; @@ -430,10 +430,10 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid, } /* Get connected, output the message to the local logger. */ -#if !defined(__minix) +#if defined(__minix) && defined(_REENTRANT) if (data == &sdata) mutex_lock(&syslog_mutex); -#endif /* !defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ opened = !data->log_opened; if (opened) openlog_unlocked_r(data->log_tag, data->log_stat, 0, data); @@ -471,10 +471,10 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid, (void)close(fd); } -#if !defined(__minix) +#if defined(__minix) && defined(_REENTRANT) if (data == &sdata) mutex_unlock(&syslog_mutex); -#endif /* !defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ if (data != &sdata && opened) { /* preserve log tag */ @@ -518,8 +518,7 @@ connectlog_r(struct syslog_data *data) if (!data->log_connected) { if (connect(data->log_file, (const struct sockaddr *)(const void *)&sun, - (socklen_t)sizeof(sun)) == -1) - { + (socklen_t)sizeof(sun)) == -1) { (void)close(data->log_file); data->log_file = -1; } else @@ -546,32 +545,32 @@ openlog_unlocked_r(const char *ident, int logstat, int logfac, void openlog_r(const char *ident, int logstat, int logfac, struct syslog_data *data) { -#if !defined(__minix) +#if defined(__minix) && defined(_REENTRANT) if (data == &sdata) mutex_lock(&syslog_mutex); -#endif /* !defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ openlog_unlocked_r(ident, logstat, logfac, data); -#if !defined(__minix) +#if defined(__minix) && defined(_REENTRANT) if (data == &sdata) mutex_unlock(&syslog_mutex); -#endif /* !defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ } void closelog_r(struct syslog_data *data) { -#if !defined(__minix) +#if defined(__minix) && defined(_REENTRANT) if (data == &sdata) mutex_lock(&syslog_mutex); -#endif /* !defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ (void)close(data->log_file); data->log_file = -1; data->log_connected = 0; data->log_tag = NULL; -#if !defined(__minix) +#if defined(__minix) && defined(_REENTRANT) if (data == &sdata) mutex_unlock(&syslog_mutex); -#endif /* !defined(__minix) */ +#endif /* defined(__minix) && defined(_REENTRANT) */ } int diff --git a/lib/libpthread/pthread.c b/lib/libpthread/pthread.c index 794f32bad..3060bf319 100644 --- a/lib/libpthread/pthread.c +++ b/lib/libpthread/pthread.c @@ -161,6 +161,8 @@ static union hashlock { * to work properly (thread-specific data is an application-visible example; * spinlock counts for mutexes is an internal example). */ + +void __pthread_init_userspace(void); void pthread__init(void) { @@ -169,6 +171,10 @@ pthread__init(void) int i; extern int __isthreaded; +#if defined(__minix) + __pthread_init_userspace(); +#endif /* defined(__minix) */ + /* * Allocate pthread_keys descriptors before * reseting __uselibcstub because otherwise diff --git a/lib/libpthread/pthread_userspace.c b/lib/libpthread/pthread_userspace.c index bb33b041e..e038f9f67 100644 --- a/lib/libpthread/pthread_userspace.c +++ b/lib/libpthread/pthread_userspace.c @@ -41,29 +41,35 @@ int pthread__cancel_stub_binder; extern void __minix_schedule(int signal __unused); -void __pthread_init_minix(void) __attribute__((__constructor__, __used__)); +void __pthread_init_userspace(void); + void -__pthread_init_minix(void) +__pthread_init_userspace(void) { int r; - static struct sigaction old_action; - static struct sigaction new_action; + static struct tls_tcb main_tls; + static struct sigaction old_action; + static struct sigaction new_action; - struct itimerval nit; - struct itimerval oit; + struct itimerval nit; + struct itimerval oit; + + print("__pthread_init_minix\n"); + _lwp_setprivate(&main_tls); + __minix_setup_main(); memset(&old_action, 0, sizeof(old_action)); memset(&new_action, 0, sizeof(new_action)); - new_action.sa_handler = __minix_schedule; - new_action.sa_flags = 0; - r = sigaction(SIGVTALRM, &new_action, &old_action); + new_action.sa_handler = __minix_schedule; + new_action.sa_flags = 0; + r = sigaction(SIGVTALRM, &new_action, &old_action); - nit.it_value.tv_sec = 0; - nit.it_value.tv_usec = 1; - nit.it_interval.tv_sec = 0; - nit.it_interval.tv_usec = 10; - r = setitimer(ITIMER_VIRTUAL, &nit, &oit); + nit.it_value.tv_sec = 0; + nit.it_value.tv_usec = 1; + nit.it_interval.tv_sec = 0; + nit.it_interval.tv_usec = 10; + r = setitimer(ITIMER_VIRTUAL, &nit, &oit); } int diff --git a/minix/lib/libc/sys/_minix_lwp.c b/minix/lib/libc/sys/_minix_lwp.c index 26960feb5..343972b53 100644 --- a/minix/lib/libc/sys/_minix_lwp.c +++ b/minix/lib/libc/sys/_minix_lwp.c @@ -28,18 +28,20 @@ struct lwp { static struct lwp lwp_threads[MAX_THREAD_POOL]; static volatile lwpid_t current_thread = 0; +static int initialized = 0; -void -__minix_schedule(int signal __unused); +void __minix_setup_main(void); +void __minix_schedule(int signal __unused); #if 0 -#define print(msg) \ - { \ - const char m[] = msg; \ - write(2, m, sizeof(m)); \ - } +#define print(args...) \ +{ \ + char buffer[200]; \ + snprintf(buffer, 200, args); \ + write(2, buffer, strlen(buffer)); \ +} #else -#define print(m) /**/ +#define print(m...) /**/ #endif static int @@ -55,13 +57,28 @@ __minix_runnable(struct lwp* thread) return 0; /* Not runnable */ } +void +__minix_setup_main(void) +{ + lwp_threads[0].flags = SLOT_IN_USE | LW_UNPARKED; +} + void __minix_schedule(int signal __unused) { + extern int __isthreaded; static int last_pos = 0; struct lwp* old = &lwp_threads[current_thread]; int pos; + /* This will be set to 1 in pthread.c, when the main thread is ready. */ + if (0 == __isthreaded) + { + return; + } + +//FIXME: LSC ADD A BARRIER TO PREVENT TWO EXECUTIONS OF THE SCHEDULE AT THE SAME TIME + /* Select Next thread to run. * Simply scan the array looking for a schedulable thread, and * loopback to the start if we reach the end. */ @@ -115,8 +132,9 @@ _lwp_makecontext(ucontext_t *context, void (*start_routine)(void *), int _lwp_create(const ucontext_t *context, unsigned long flags, lwpid_t *new_lwp) { - size_t i = 0; + size_t i = 1; // Skip slot 0 which is main thread + print("_lwp_create\n"); while ((i < MAX_THREAD_POOL) && (SLOT_IN_USE == (lwp_threads[i].flags & SLOT_IN_USE))) { i++; @@ -236,15 +254,16 @@ _lwp_getname(lwpid_t target, char * name, size_t len) void * _lwp_getprivate(void) { -// print("_lwp_getprivate\n"); +// print("_lwp_getprivate %08x %08x %08x\n", lwp_threads, &lwp_threads[current_thread], lwp_threads[current_thread].tls); return lwp_threads[current_thread].tls; } void _lwp_setprivate(void *cookie) { - print("_lwp_setprivate\n"); +// print("_lwp_setprivate %08x\n", cookie); lwp_threads[current_thread].tls = cookie; +// print("_lwp_setprivate %08x %08x %08x %08x\n", lwp_threads, &lwp_threads[current_thread], lwp_threads[current_thread].tls, cookie); } int