diff options
Diffstat (limited to 'libthreads/i386')
-rw-r--r-- | libthreads/i386/csw.S | 185 | ||||
-rw-r--r-- | libthreads/i386/cthread_inline.awk | 86 | ||||
-rw-r--r-- | libthreads/i386/cthreads.h | 89 | ||||
-rw-r--r-- | libthreads/i386/lock.s | 70 | ||||
-rw-r--r-- | libthreads/i386/thread.c | 123 |
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; +} + |