diff options
Diffstat (limited to 'libpthread/pthread.c')
-rw-r--r-- | libpthread/pthread.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/libpthread/pthread.c b/libpthread/pthread.c new file mode 100644 index 000000000..a7e5ba10e --- /dev/null +++ b/libpthread/pthread.c @@ -0,0 +1,106 @@ +/* vi: set sw=4 ts=4: */ +/* + * A simple clopne based pthread implementation + * + * Copyright (C) 2001 by Erik Andersen <andersee@debian.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdlib.h> +#include <sched.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <pthread.h> + +#define STACKSIZE 8096 + +#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ +#define CLONE_VM 0x00000100 /* set if VM shared between processes */ +#define CLONE_FS 0x00000200 /* set if fs info shared between proces ses */ +#define CLONE_FILES 0x00000400 /* set if open files shared between pro cesses */ +#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */ + + + +/* Lame home-grown clone based threading */ +int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutex_attr) +{ + mutex->__m_lock.__spinlock = 1; + return 0; +} + +int pthread_mutex_lock (pthread_mutex_t *mutex) +{ + while (mutex->__m_lock.__spinlock == 0) { + usleep(10000); + } + --(mutex->__m_lock.__spinlock); + return 0; +} + +int pthread_mutex_unlock (pthread_mutex_t *mutex) +{ + ++(mutex->__m_lock.__spinlock); + return 0; +} + +int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + ++(mutex->__m_lock.__spinlock); + while (cond->__c_lock.__spinlock == 0) { + usleep(10000); + } + --(cond->__c_lock.__spinlock); + return 0; +} + +int pthread_cond_signal(pthread_cond_t *cond) +{ + ++(cond->__c_lock.__spinlock); + return 0; +} + +int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr) +{ + cond->__c_lock.__spinlock = 1; + return 0; +} + +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void* (*fn)(void *), void *data) +{ + long retval; + void **newstack; + int (*clonefunc)(void *) = (int (*)(void *))(fn); + + newstack = (void **) malloc(STACKSIZE); + if (!newstack) + return -1; + newstack = (void **) (STACKSIZE + (char *) newstack); + *--newstack = data; + retval = clone(clonefunc, newstack, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD, data); + if (retval < 0) { + errno = -retval; + *thread = 0; + retval = -1; + } else { + *thread = retval; + retval = 0; + } + return retval; +} + |