diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-11-14 06:46:51 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-11-14 06:46:51 +0000 |
commit | 40f41cdcdbd34179b696a7466344524e2d0c0222 (patch) | |
tree | 75a5c872540c9b38c48b2a4c7bc7f235a29614aa /libpthread | |
parent | e8e2384f2ed57515873b81914c2999735856b02e (diff) | |
download | uClibc-alpine-40f41cdcdbd34179b696a7466344524e2d0c0222.tar.bz2 uClibc-alpine-40f41cdcdbd34179b696a7466344524e2d0c0222.tar.xz |
Initial first (lame) pass at making a pthreads library. This
works for me when linking staticly on x86.
Diffstat (limited to 'libpthread')
-rw-r--r-- | libpthread/Makefile | 61 | ||||
-rw-r--r-- | libpthread/pthread.c | 106 |
2 files changed, 167 insertions, 0 deletions
diff --git a/libpthread/Makefile b/libpthread/Makefile new file mode 100644 index 000000000..6c10431af --- /dev/null +++ b/libpthread/Makefile @@ -0,0 +1,61 @@ +# Makefile for uClibc +# +# Copyright (C) 2000 by by Lineo, inc. and Erik Andersen +# Copyright (C) 2000, 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 Library 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 Library General Public License for more +# details. +# +# You should have received a copy of the GNU Library 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 +# +# Derived in part from the Linux-8086 C library, the GNU C Library, and several +# other sundry sources. Files within this library are copyright by their +# respective copyright holders. + +TOPDIR=../ +include $(TOPDIR)Rules.mak + +LIBPTHREAD=libpthread.a +LIBPTHREAD_SHARED=libpthread.so +LIBPTHREAD_SHARED_FULLNAME=libpthread-$(MAJOR_VERSION).$(MINOR_VERSION).so + +CSRC = pthread.c +OBJS=$(patsubst %.c,%.o, $(CSRC)) + +all: $(OBJS) $(LIBPTHREAD) + +$(LIBPTHREAD): ar-target + +ar-target: $(OBJS) + $(AR) $(ARFLAGS) $(LIBPTHREAD) $(OBJS) + install -d $(TOPDIR)lib + rm -f $(TOPDIR)lib/$(LIBPTHREAD) + install -m 644 $(LIBPTHREAD) $(TOPDIR)lib + +$(OBJS): %.o : %.c + $(TARGET_CC) $(TARGET_CFLAGS) -c $< -o $@ + $(STRIPTOOL) -x -R .note -R .comment $*.o + +$(OBJ): Makefile + +shared: all + $(TARGET_CC) $(TARGET_LDFLAGS) -nostdlib -shared -o $(LIBPTHREAD_SHARED_FULLNAME) \ + -Wl,-soname,$(LIBPTHREAD_SHARED).$(MAJOR_VERSION) -Wl,--whole-archive $(LIBPTHREAD) -lc + install -d $(TOPDIR)lib + rm -f $(TOPDIR)lib/$(LIBPTHREAD_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBPTHREAD_SHARED).$(MAJOR_VERSION) + install -m 644 $(LIBPTHREAD_SHARED_FULLNAME) $(TOPDIR)lib; + (cd $(TOPDIR)lib; ln -sf $(LIBPTHREAD_SHARED_FULLNAME) $(LIBPTHREAD_SHARED)); + (cd $(TOPDIR)lib; ln -sf $(LIBPTHREAD_SHARED_FULLNAME) $(LIBPTHREAD_SHARED).$(MAJOR_VERSION)); + +clean: + rm -f *.[oa] *~ core $(LIBPTHREAD_SHARED)* $(LIBPTHREAD_SHARED_FULLNAME)* + 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; +} + |