summaryrefslogtreecommitdiff
path: root/libpthread
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-11-14 06:46:51 +0000
committerEric Andersen <andersen@codepoet.org>2001-11-14 06:46:51 +0000
commit40f41cdcdbd34179b696a7466344524e2d0c0222 (patch)
tree75a5c872540c9b38c48b2a4c7bc7f235a29614aa /libpthread
parente8e2384f2ed57515873b81914c2999735856b02e (diff)
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/Makefile61
-rw-r--r--libpthread/pthread.c106
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;
+}
+