aboutsummaryrefslogtreecommitdiff
path: root/libthreads/i386
diff options
context:
space:
mode:
Diffstat (limited to 'libthreads/i386')
-rw-r--r--libthreads/i386/csw.S185
-rw-r--r--libthreads/i386/cthread_inline.awk86
-rw-r--r--libthreads/i386/cthreads.h89
-rw-r--r--libthreads/i386/lock.s70
-rw-r--r--libthreads/i386/thread.c123
5 files changed, 553 insertions, 0 deletions
diff --git a/libthreads/i386/csw.S b/libthreads/i386/csw.S
new file mode 100644
index 00000000..5579db5c
--- /dev/null
+++ b/libthreads/i386/csw.S
@@ -0,0 +1,185 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * HISTORY
+ * $Log: csw.S,v $
+ * Revision 1.8 1997/04/04 01:31:16 thomas
+ * Thu Apr 3 20:29:27 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+ *
+ * * i386/csw.S: Define __ELF__ too.
+ *
+ * Revision 1.7 1996/10/24 19:30:10 thomas
+ * Mon Oct 21 22:05:48 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+ *
+ * * i386/csw.S (CALL_MCOUNT): New macro.
+ * (cproc_swtich, cproc_start_wait, cproc_prepare): Use CALL_MCOUNT.
+ *
+ * Revision 1.6 1996/08/29 17:44:42 thomas
+ * *** empty log message ***
+ *
+ * Revision 1.5 1995/10/04 20:55:28 roland
+ * (JUMPTARGET): New macro, versions for [PIC] and not.
+ * Use it in place of EXT.
+ *
+ * Revision 1.4 1995/10/04 20:22:17 roland
+ * [PIC] (EXT): Redefine to use PLT.
+ *
+ * Revision 1.3 1995/05/12 18:35:55 roland
+ * Use EXT macro instead of explicit underscores.
+ *
+# Revision 1.2 1994/05/04 19:01:50 mib
+# entered into RCS
+#
+ * Revision 2.7 91/07/31 18:36:32 dbg
+ * Fix for ANSI C preprocessor.
+ * [91/07/30 17:35:16 dbg]
+ *
+ * Revision 2.6 91/05/14 17:56:56 mrt
+ * Correcting copyright
+ *
+ * Revision 2.5 91/05/08 13:35:49 dbg
+ * Unlock lock with a locked instruction (xchg).
+ * [91/03/20 dbg]
+ *
+ * Revision 2.4 91/02/14 14:20:02 mrt
+ * Changed to new Mach copyright
+ * [91/02/13 12:15:27 mrt]
+ *
+ * Revision 2.3 91/01/08 16:46:20 rpd
+ * Don't use Times - horta doesn't like it for some reason.
+ * [91/01/06 rpd]
+ *
+ * Revision 2.2 90/05/03 15:54:37 dbg
+ * Created.
+ * [90/02/05 dbg]
+ *
+ */
+#define ELF
+#define __ELF__
+#include <mach/i386/asm.h>
+
+#ifdef PIC
+#define JUMPTARGET(name) EXT(name##@PLT)
+#else
+#define JUMPTARGET(name) EXT(name)
+#endif
+
+#ifdef PROF
+#define CALL_MCOUNT \
+ pushl %ebp; movl %esp, %ebp; call JUMPTARGET(mcount); popl %ebp;
+#else
+#define CALL_MCOUNT
+#endif
+
+
+/*
+ * Suspend the current thread and resume the next one.
+ *
+ * void cproc_switch(int *cur, int *next, int *lock)
+ */
+ENTRY(cproc_switch)
+ CALL_MCOUNT
+ pushl %ebp /* save ebp */
+ movl %esp,%ebp /* set frame pointer to get arguments */
+ pushl %ebx /* save ebx */
+ pushl %esi /* esi */
+ pushl %edi /* edi */
+ movl B_ARG0,%eax /* get cur */
+ movl %esp,(%eax) /* save current esp */
+ movl B_ARG2,%edx /* get address of lock before switching */
+ /* stacks */
+ movl B_ARG1,%eax /* get next */
+ movl (%eax),%esp /* get new stack pointer */
+ xorl %eax,%eax /* unlock */
+ xchgl %eax,(%edx) /* the lock - now old thread can run */
+
+ popl %edi /* restore di */
+ popl %esi /* si */
+ popl %ebx /* bx */
+ popl %ebp /* and bp (don`t use "leave" - bp */
+ /* still points to old stack) */
+ ret
+
+/*
+ * Create a new stack frame for a 'waiting' thread,
+ * save current thread's frame, and switch to waiting thread.
+ *
+ * void cproc_start_wait(int *cur,
+ * cproc_t child,
+ * int stackp,
+ * int *lock)
+ */
+ENTRY(cproc_start_wait)
+ CALL_MCOUNT
+ pushl %ebp /* save ebp */
+ movl %esp,%ebp /* set frame pointer */
+ pushl %ebx /* save ebx */
+ pushl %esi /* esi */
+ pushl %edi /* edi */
+ movl B_ARG0,%eax /* get cur */
+ movl %esp,(%eax) /* save current esp */
+ movl B_ARG1,%eax /* get child thread */
+ movl B_ARG3,%edx /* point to lock before switching stack */
+ movl B_ARG2,%esp /* get new stack */
+ pushl %eax /* push child thread as argument */
+ movl $0,%ebp /* (clear frame pointer) */
+ xorl %eax,%eax /* unlock */
+ xchgl %eax,(%edx) /* the lock - now old thread can run */
+ call JUMPTARGET(cproc_waiting)/* call cproc_waiting */
+ /*NOTREACHED*/
+
+/*
+ * Set up a thread's stack so that when cproc_switch switches to
+ * it, it will start up as if it called
+ * cproc_body(child)
+ *
+ * void cproc_prepare(cproc_t child, int *context, int stack,
+ * void (*cthread_body)(cproc_t));
+ */
+ENTRY(cproc_prepare)
+ CALL_MCOUNT
+ pushl %ebp /* save ebp */
+ movl %esp,%ebp /* set frame pointer */
+ movl B_ARG2,%edx /* get child`s stack */
+ subl $28,%edx
+ /* make room for context: */
+ /* 0 saved edi () */
+ /* 4 saved esi () */
+ /* 8 saved ebx () */
+ /* 12 saved ebp () */
+ /* 16 return PC from cproc_switch */
+ /* 20 return PC from cthread_body */
+ /* 24 argument to cthread_body */
+ movl $0,12(%edx) /* clear frame pointer */
+ movl B_ARG3,%ecx /* get address of cthread_body passed in */
+ movl %ecx,16(%edx) /* set child to resume at cthread_body */
+ movl $0,20(%edx) /* fake return address from cthread_body */
+ movl B_ARG0,%ecx /* get child thread pointer */
+ movl %ecx,24(%edx) /* set as argument to cthread_body */
+ movl B_ARG1,%ecx /* get pointer to context */
+ movl %edx,(%ecx) /* save context */
+ leave
+ ret
diff --git a/libthreads/i386/cthread_inline.awk b/libthreads/i386/cthread_inline.awk
new file mode 100644
index 00000000..8e0cb7d4
--- /dev/null
+++ b/libthreads/i386/cthread_inline.awk
@@ -0,0 +1,86 @@
+#
+# Mach Operating System
+# Copyright (c) 1991,1990 Carnegie Mellon University
+# All Rights Reserved.
+#
+# Permission to use, copy, modify and distribute this software and its
+# documentation is hereby granted, provided that both the copyright
+# notice and this permission notice appear in all copies of the
+# software, derivative works or modified versions, and any portions
+# thereof, and that both notices appear in supporting documentation.
+#
+# CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+# CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+# ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+#
+# Carnegie Mellon requests users of this software to return to
+#
+# Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+# School of Computer Science
+# Carnegie Mellon University
+# Pittsburgh PA 15213-3890
+#
+# any improvements or extensions that they make and grant Carnegie Mellon
+# the rights to redistribute these changes.
+#
+#
+# HISTORY
+# $Log: cthread_inline.awk,v $
+# Revision 2.5 91/05/14 17:57:03 mrt
+# Correcting copyright
+#
+# Revision 2.4 91/05/08 13:36:05 dbg
+# Unlock lock with a locked instruction (xchg).
+# [91/03/20 dbg]
+#
+# Revision 2.3 91/02/14 14:20:06 mrt
+# Added new Mach copyright
+# [91/02/13 12:33:05 mrt]
+#
+# Revision 2.2 90/05/03 15:54:56 dbg
+# Created (from 68020 version).
+# [90/02/05 dbg]
+#
+# Revision 2.2 89/12/08 19:54:30 rwd
+# Inlines are now spins instead of mutexes.
+# [89/10/23 rwd]
+#
+# Revision 2.1 89/08/04 15:15:14 rwd
+# Created.
+#
+# Revision 1.3 89/05/05 19:00:33 mrt
+# Cleanup for Mach 2.5
+#
+#
+
+# sun/cthread_inline.awk
+#
+# Awk script to inline critical C Threads primitives on i386
+
+NF == 2 && $1 == "call" && $2 == "_spin_try_lock" {
+ print "/ BEGIN INLINE spin_try_lock"
+ print " movl (%esp),%ecx / point at mutex"
+ print " movl $1,%eax / set locked value in acc"
+ print " xchg %eax,(%ecx) / locked swap with mutex"
+ print " xorl $1,%eax / logical complement"
+ print "/ END INLINE spin_try_lock"
+ continue
+}
+NF == 2 && $1 == "call" && $2 == "_spin_unlock" {
+ print "/ BEGIN INLINE " $2
+ print " movl (%esp),%ecx"
+ print " xorl %eax,%eax / set unlocked value in acc"
+ print " xchg %eax,(%ecx) / locked swap with mutex"
+ print "/ END INLINE " $2
+ continue
+}
+NF == 2 && $1 == "call" && $2 == "_cthread_sp" {
+ print "/ BEGIN INLINE cthread_sp"
+ print " movl %esp,%eax"
+ print "/ END INLINE cthread_sp"
+ continue
+}
+# default:
+{
+ print
+}
diff --git a/libthreads/i386/cthreads.h b/libthreads/i386/cthreads.h
new file mode 100644
index 00000000..8ffe4b72
--- /dev/null
+++ b/libthreads/i386/cthreads.h
@@ -0,0 +1,89 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * HISTORY
+ * $Log: cthreads.h,v $
+ * Revision 2.7 92/01/03 20:36:59 dbg
+ * Add volatile to spin_lock_t. Change spin_unlock and
+ * spin_try_lock definitions back to memory operands, but rely on
+ * volatile attribute to keep from using value in memory.
+ * [91/09/04 dbg]
+ *
+ * Revision 2.6 91/08/28 20:18:39 jsb
+ * Safer definitions for spin_unlock and spin_try_lock from mib.
+ *
+ * Revision 2.5 91/07/31 18:36:49 dbg
+ * Add inline substitution for cthread_sp, spin_unlock,
+ * spin_try_lock.
+ * [91/07/30 17:35:53 dbg]
+ *
+ * Revision 2.4 91/05/14 17:57:11 mrt
+ * Correcting copyright
+ *
+ * Revision 2.3 91/02/14 14:20:14 mrt
+ * Changed to new Mach copyright
+ * [91/02/13 12:20:00 mrt]
+ *
+ * Revision 2.2 90/11/05 14:37:23 rpd
+ * Created.
+ * [90/11/01 rwd]
+ *
+ *
+ */
+
+#ifndef _MACHINE_CTHREADS_H_
+#define _MACHINE_CTHREADS_H_
+
+typedef volatile int spin_lock_t;
+#define SPIN_LOCK_INITIALIZER 0
+#define spin_lock_init(s) (*(s) = 0)
+#define spin_lock_locked(s) (*(s) != 0)
+
+#ifdef __GNUC__
+
+#define spin_unlock(p) \
+ ({ register int _u__ ; \
+ asm volatile("xorl %0, %0; \n\
+ xchgl %0, %1" \
+ : "=&r" (_u__), "=m" (*(p)) ); \
+ 0; })
+
+#define spin_try_lock(p)\
+ ({ boolean_t _r__; \
+ asm volatile("movl $1, %0; \n\
+ xchgl %0, %1" \
+ : "=&r" (_r__), "=m" (*(p)) ); \
+ !_r__; })
+
+#define cthread_sp() \
+ ({ int _sp__; \
+ asm("movl %%esp, %0" \
+ : "=g" (_sp__) ); \
+ _sp__; })
+
+#endif /* __GNUC__ */
+
+#endif _MACHINE_CTHREADS_H_
diff --git a/libthreads/i386/lock.s b/libthreads/i386/lock.s
new file mode 100644
index 00000000..e27fa7ff
--- /dev/null
+++ b/libthreads/i386/lock.s
@@ -0,0 +1,70 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * HISTORY
+ * $Log: lock.s,v $
+ * Revision 2.5 91/05/14 17:57:20 mrt
+ * Correcting copyright
+ *
+ * Revision 2.4 91/05/08 13:36:15 dbg
+ * Unlock lock with a locked instruction (xchg).
+ * [91/03/20 dbg]
+ *
+ * Revision 2.3 91/02/14 14:20:18 mrt
+ * Changed to new Mach copyright
+ * [91/02/13 12:20:06 mrt]
+ *
+ * Revision 2.2 90/05/03 15:54:59 dbg
+ * Created.
+ * [90/02/05 dbg]
+ *
+ */
+
+#include <i386/asm.h>
+
+/*
+ * boolean_t spin_try_lock(int *m)
+ */
+ENTRY(spin_try_lock)
+ movl 4(%esp),%ecx / point at mutex
+ movl $1,%eax / set locked value in acc
+ xchg %eax,(%ecx) / swap with mutex
+ / xchg with memory is automatically
+ / locked
+ xorl $1,%eax / 1 (locked) => FALSE
+ / 0 (locked) => TRUE
+ ret
+
+/*
+ * void spin_unlock(int *m)
+ */
+ENTRY(spin_unlock)
+ movl 4(%esp),%ecx / point at mutex
+ xorl %eax,%eax / set unlocked value in acc
+ xchg %eax,(%ecx) / swap with mutex
+ / xchg with memory is automatically
+ / locked
+ ret
diff --git a/libthreads/i386/thread.c b/libthreads/i386/thread.c
new file mode 100644
index 00000000..38f91192
--- /dev/null
+++ b/libthreads/i386/thread.c
@@ -0,0 +1,123 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * HISTORY
+ * $Log: thread.c,v $
+ * Revision 1.2 1994/05/04 19:05:26 mib
+ * entered into RCS
+ *
+ * Revision 2.6 91/07/31 18:37:07 dbg
+ * Undefine cthread_sp macro around function definition.
+ * [91/07/30 17:36:23 dbg]
+ *
+ * Revision 2.5 91/05/14 17:57:27 mrt
+ * Correcting copyright
+ *
+ * Revision 2.4 91/02/14 14:20:21 mrt
+ * Changed to new Mach copyright
+ * [91/02/13 12:20:10 mrt]
+ *
+ * Revision 2.3 90/06/02 15:13:53 rpd
+ * Added definition of cthread_sp.
+ * [90/06/02 rpd]
+ *
+ * Revision 2.2 90/05/03 15:55:03 dbg
+ * Created (from 68020 version).
+ * [90/02/05 dbg]
+ *
+ */
+/*
+ * i386/thread.c
+ *
+ */
+
+#ifndef lint
+static char rcs_id[] = "$Header: cvs-sans-libpthread/hurd/libthreads/i386/thread.c,v 1.3 1997/02/18 22:53:31 miles Exp $";
+#endif not lint
+
+
+#include "../cthreads.h"
+#include "../cthread_internals.h"
+
+
+#include <mach/mach.h>
+
+/*
+ * C library imports:
+ */
+extern bzero();
+
+/*
+ * Set up the initial state of a MACH thread
+ * so that it will invoke cthread_body(child)
+ * when it is resumed.
+ */
+void
+cproc_setup(child, thread, routine)
+ register cproc_t child;
+ int thread;
+ int routine;
+{
+ extern unsigned int __hurd_threadvar_max; /* GNU */
+ register int *top = (int *)
+ cproc_stack_base (child,
+ sizeof(ur_cthread_t *) +
+ /* Account for GNU per-thread variables. */
+ __hurd_threadvar_max *
+ sizeof (long int));
+ struct i386_thread_state state;
+ register struct i386_thread_state *ts = &state;
+ kern_return_t r;
+ unsigned int count;
+
+ /*
+ * Set up i386 call frame and registers.
+ * Read registers first to get correct segment values.
+ */
+ count = i386_THREAD_STATE_COUNT;
+ MACH_CALL(thread_get_state(thread,i386_THREAD_STATE,(thread_state_t) &state,&count),r);
+
+ ts->eip = routine;
+ *--top = (int) child; /* argument to function */
+ *--top = 0; /* fake return address */
+ ts->uesp = (int) top; /* set stack pointer */
+ ts->ebp = 0; /* clear frame pointer */
+
+ MACH_CALL(thread_set_state(thread,i386_THREAD_STATE,(thread_state_t) &state,i386_THREAD_STATE_COUNT),r);
+}
+
+#ifdef cthread_sp
+#undef cthread_sp
+#endif
+
+int
+cthread_sp()
+{
+ int x;
+
+ return (int) &x;
+}
+