recent changes

This commit is contained in:
Russ Cox 2011-01-03 15:08:59 -05:00
parent 42f058999e
commit b75fdf3424
9 changed files with 462 additions and 15 deletions

View File

@ -48,9 +48,6 @@ testdelay1: testdelay1.o $(LIB)
clean:
rm -f *.o primes tcpproxy testdelay testdelay1 httpload $(LIB)
tgz:
tar czvf libtask.tgz COPYRIGHT README *.[chS] Makefile makesun
install: $(LIB)
cp $(LIB) /usr/local/lib
cp task.h /usr/local/include

57
Makefile.sun Normal file
View File

@ -0,0 +1,57 @@
LIB=libtask.a
OFILES=\
channel.o\
context.o\
fd.o\
net.o\
print.o\
qlock.o\
rendez.o\
task.o\
all: $(LIB) primes tcpproxy testdelay
$(OFILES): taskimpl.h task.h 386-ucontext.h power-ucontext.h
AS=as
CC=cc
CFLAGS=-c -I. -g
%.o: %.S
$(AS) $*.S
%.o: %.c
$(CC) $(CFLAGS) $*.c
$(LIB): $(OFILES)
ar rvc $(LIB) $(OFILES)
primes: primes.o $(LIB)
$(CC) -o primes primes.o $(LIB)
tcpproxy: tcpproxy.o $(LIB)
$(CC) -o tcpproxy tcpproxy.o $(LIB)
httpload: httpload.o $(LIB)
$(CC) -o httpload httpload.o $(LIB)
stdlogger: stdlogger.o $(LIB)
$(CC) -o stdlogger stdlogger.o $(LIB)
testdelay: testdelay.o $(LIB)
$(CC) -o testdelay testdelay.o $(LIB)
clock: clock.o $(LIB)
$(CC) -o clock clock.o $(LIB)
clean:
rm *.o tcpproxy primes $(LIB)
tgz:
tar czvf libtask.tgz COPYRIGHT README *.[chS] Makefile
install: $(LIB)
cp $(LIB) /usr/local/lib
cp task.h /usr/local/include

6
README
View File

@ -1,6 +1,6 @@
Libtask is a simple coroutine library. It runs on Linux (ARM and x86),
FreeBSD (x86), OS X (PowerPC and x86), and SunOS Solaris (Sparc), and is
easy to port to other systems.
Libtask is a simple coroutine library. It runs on Linux (ARM, MIPS, and x86),
FreeBSD (x86), OS X (PowerPC x86, and x86-64), and SunOS Solaris (Sparc),
and is easy to port to other systems.
Libtask gives the programmer the illusion of threads, but
the operating system sees only a single kernel thread.

137
amd64-ucontext.h Normal file
View File

@ -0,0 +1,137 @@
#define setcontext(u) setmcontext(&(u)->uc_mcontext)
#define getcontext(u) getmcontext(&(u)->uc_mcontext)
typedef struct mcontext mcontext_t;
typedef struct ucontext ucontext_t;
extern int swapcontext(ucontext_t*, const ucontext_t*);
extern void makecontext(ucontext_t*, void(*)(), int, ...);
extern int getmcontext(mcontext_t*);
extern void setmcontext(const mcontext_t*);
/*-
* Copyright (c) 1999 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/sys/ucontext.h,v 1.4 1999/10/11 20:33:17 luoqi Exp $
*/
/* #include <machine/ucontext.h> */
/*-
* Copyright (c) 1999 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/include/ucontext.h,v 1.4 1999/10/11 20:33:09 luoqi Exp $
*/
struct mcontext {
/*
* The first 20 fields must match the definition of
* sigcontext. So that we can support sigcontext
* and ucontext_t at the same time.
*/
long mc_onstack; /* XXX - sigcontext compat. */
long mc_rdi; /* machine state (struct trapframe) */
long mc_rsi;
long mc_rdx;
long mc_rcx;
long mc_r8;
long mc_r9;
long mc_rax;
long mc_rbx;
long mc_rbp;
long mc_r10;
long mc_r11;
long mc_r12;
long mc_r13;
long mc_r14;
long mc_r15;
long mc_trapno;
long mc_addr;
long mc_flags;
long mc_err;
long mc_rip;
long mc_cs;
long mc_rflags;
long mc_rsp;
long mc_ss;
long mc_len; /* sizeof(mcontext_t) */
#define _MC_FPFMT_NODEV 0x10000 /* device not present or configured */
#define _MC_FPFMT_XMM 0x10002
long mc_fpformat;
#define _MC_FPOWNED_NONE 0x20000 /* FP state not used */
#define _MC_FPOWNED_FPU 0x20001 /* FP state came from FPU */
#define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */
long mc_ownedfp;
/*
* See <machine/fpu.h> for the internals of mc_fpstate[].
*/
long mc_fpstate[64];
long mc_spare[8];
};
struct ucontext {
/*
* Keep the order of the first two fields. Also,
* keep them the first two fields in the structure.
* This way we can have a union with struct
* sigcontext and ucontext_t. This allows us to
* support them both at the same time.
* note: the union is not defined, though.
*/
sigset_t uc_sigmask;
mcontext_t uc_mcontext;
struct __ucontext *uc_link;
stack_t uc_stack;
int __spare__[8];
};

128
asm.S
View File

@ -12,17 +12,21 @@
#define GET getmcontext
#endif
#if defined(__APPLE__) && defined(__i386__)
#if defined(__APPLE__)
#if defined(__i386__)
#define NEEDX86CONTEXT 1
#define SET _setmcontext
#define GET _getmcontext
#endif
#if defined(__APPLE__) && !defined(__i386__)
#elif defined(__x86_64__)
#define NEEDAMD64CONTEXT 1
#define SET _setmcontext
#define GET _getmcontext
#else
#define NEEDPOWERCONTEXT 1
#define SET __setmcontext
#define GET __getmcontext
#endif
#endif
#if defined(__linux__) && defined(__arm__)
#define NEEDARMCONTEXT 1
@ -30,6 +34,12 @@
#define GET getmcontext
#endif
#if defined(__linux__) && defined(__mips__)
#define NEEDMIPSCONTEXT 1
#define SET setmcontext
#define GET getmcontext
#endif
#ifdef NEEDX86CONTEXT
.globl SET
SET:
@ -77,6 +87,56 @@ GET:
ret
#endif
#ifdef NEEDAMD64CONTEXT
.globl SET
SET:
movq 16(%rdi), %rsi
movq 24(%rdi), %rdx
movq 32(%rdi), %rcx
movq 40(%rdi), %r8
movq 48(%rdi), %r9
movq 56(%rdi), %rax
movq 64(%rdi), %rbx
movq 72(%rdi), %rbp
movq 80(%rdi), %r10
movq 88(%rdi), %r11
movq 96(%rdi), %r12
movq 104(%rdi), %r13
movq 112(%rdi), %r14
movq 120(%rdi), %r15
movq 184(%rdi), %rsp
pushq 160(%rdi) /* new %eip */
movq 8(%rdi), %rdi
ret
.globl GET
GET:
movq %rdi, 8(%rdi)
movq %rsi, 16(%rdi)
movq %rdx, 24(%rdi)
movq %rcx, 32(%rdi)
movq %r8, 40(%rdi)
movq %r9, 48(%rdi)
movq $1, 56(%rdi) /* %rax */
movq %rbx, 64(%rdi)
movq %rbp, 72(%rdi)
movq %r10, 80(%rdi)
movq %r11, 88(%rdi)
movq %r12, 96(%rdi)
movq %r13, 104(%rdi)
movq %r14, 112(%rdi)
movq %r15, 120(%rdi)
movq (%rsp), %rcx /* %rip */
movq %rcx, 160(%rdi)
leaq 8(%rsp), %rcx /* %rsp */
movq %rcx, 184(%rdi)
movq 32(%rdi), %rcx /* restore %rcx */
movq $0, %rax
ret
#endif
#ifdef NEEDPOWERCONTEXT
/* get FPR and VR use flags with sc 0x7FF3 */
/* get vsave with mfspr reg, 256 */
@ -204,3 +264,63 @@ SET:
ldr r0, [r0]
mov pc, lr
#endif
#ifdef NEEDMIPSCONTEXT
.globl GET
GET:
sw $4, 24($4)
sw $5, 28($4)
sw $6, 32($4)
sw $7, 36($4)
sw $16, 72($4)
sw $17, 76($4)
sw $18, 80($4)
sw $19, 84($4)
sw $20, 88($4)
sw $21, 92($4)
sw $22, 96($4)
sw $23, 100($4)
sw $28, 120($4) /* gp */
sw $29, 124($4) /* sp */
sw $30, 128($4) /* fp */
sw $31, 132($4) /* ra */
xor $2, $2, $2
j $31
nop
.globl SET
SET:
lw $16, 72($4)
lw $17, 76($4)
lw $18, 80($4)
lw $19, 84($4)
lw $20, 88($4)
lw $21, 92($4)
lw $22, 96($4)
lw $23, 100($4)
lw $28, 120($4) /* gp */
lw $29, 124($4) /* sp */
lw $30, 128($4) /* fp */
/*
* If we set $31 directly and j $31,
* we would loose the outer return address.
* Use a temporary register, then.
*/
lw $8, 132($4) /* ra */
/* bug: not setting the pc causes a bus error */
lw $25, 132($4) /* pc */
lw $5, 28($4)
lw $6, 32($4)
lw $7, 36($4)
lw $4, 24($4)
j $8
nop
#endif

View File

@ -2,15 +2,18 @@
#include "taskimpl.h"
#if defined(__APPLE__) && defined(__i386__)
#if defined(__APPLE__)
#if defined(__i386__)
#define NEEDX86MAKECONTEXT
#define NEEDSWAPCONTEXT
#endif
#if defined(__APPLE__) && !defined(__i386__)
#elif defined(__x86_64__)
#define NEEDAMD64MAKECONTEXT
#define NEEDSWAPCONTEXT
#else
#define NEEDPOWERMAKECONTEXT
#define NEEDSWAPCONTEXT
#endif
#endif
#if defined(__FreeBSD__) && defined(__i386__) && __FreeBSD__ < 5
#define NEEDX86MAKECONTEXT
@ -27,6 +30,11 @@
#define NEEDARMMAKECONTEXT
#endif
#if defined(__linux__) && defined(__mips__)
#define NEEDSWAPCONTEXT
#define NEEDMIPSMAKECONTEXT
#endif
#ifdef NEEDPOWERMAKECONTEXT
void
makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
@ -61,6 +69,29 @@ makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
}
#endif
#ifdef NEEDAMD64MAKECONTEXT
void
makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
long *sp;
va_list va;
memset(&ucp->uc_mcontext, 0, sizeof ucp->uc_mcontext);
if(argc != 2)
*(int*)0 = 0;
va_start(va, argc);
ucp->uc_mcontext.mc_rdi = va_arg(va, int);
ucp->uc_mcontext.mc_rsi = va_arg(va, int);
va_end(va);
sp = (long*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/sizeof(long);
sp -= argc;
sp = (void*)((uintptr_t)sp - (uintptr_t)sp%16); /* 16-align for OS X */
*--sp = 0; /* return address */
ucp->uc_mcontext.mc_rip = (long)func;
ucp->uc_mcontext.mc_rsp = (long)sp;
}
#endif
#ifdef NEEDARMMAKECONTEXT
void
makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
@ -78,6 +109,23 @@ makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
}
#endif
#ifdef NEEDMIPSMAKECONTEXT
void
makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
{
int i, *sp;
va_list arg;
va_start(arg, argc);
sp = (int*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size/4;
for(i=0; i<4 && i<argc; i++)
uc->uc_mcontext.mc_regs[i+4] = va_arg(arg, int);
va_end(arg);
uc->uc_mcontext.mc_regs[29] = (int)sp;
uc->uc_mcontext.mc_regs[31] = (int)fn;
}
#endif
#ifdef NEEDSWAPCONTEXT
int
swapcontext(ucontext_t *oucp, const ucontext_t *ucp)

77
mips-ucontext.h Normal file
View File

@ -0,0 +1,77 @@
typedef struct mcontext mcontext_t;
typedef struct ucontext ucontext_t;
extern int swapcontext(ucontext_t*, const ucontext_t*);
extern void makecontext(ucontext_t*, void(*)(), int, ...);
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ralph Campbell.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ucontext.h 8.1 (Berkeley) 6/10/93
* JNPR: ucontext.h,v 1.2 2007/08/09 11:23:32 katta
* $FreeBSD: src/sys/mips/include/ucontext.h,v 1.2 2010/01/10 19:50:24 imp Exp $
*/
struct mcontext {
/*
* These fields must match the corresponding fields in struct
* sigcontext which follow 'sc_mask'. That way we can support
* struct sigcontext and ucontext_t at the same time.
*/
int mc_onstack; /* sigstack state to restore */
int mc_pc; /* pc at time of signal */
int mc_regs[32]; /* processor regs 0 to 31 */
int sr; /* status register */
int mullo, mulhi; /* mullo and mulhi registers... */
int mc_fpused; /* fp has been used */
int mc_fpregs[33]; /* fp regs 0 to 31 and csr */
int mc_fpc_eir; /* fp exception instruction reg */
void *mc_tls; /* pointer to TLS area */
int __spare__[8]; /* XXX reserved */
};
struct ucontext {
/*
* Keep the order of the first two fields. Also,
* keep them the first two fields in the structure.
* This way we can have a union with struct
* sigcontext and ucontext_t. This allows us to
* support them both at the same time.
* note: the union is not defined, though.
*/
sigset_t uc_sigmask;
mcontext_t uc_mcontext;
struct __ucontext *uc_link;
stack_t uc_stack;
int uc_flags;
int __spare__[4];
};

1
task.c
View File

@ -123,6 +123,7 @@ taskalloc(void (*fn)(void*), void *arg, uint stack)
* function that takes some number of word-sized variables,
* and on 64-bit machines pointers are bigger than words.
*/
//print("make %p\n", t);
z = (ulong)t;
y = z;
z >>= 16; /* hide undefined 32-bit shift from 32-bit compilers */

View File

@ -11,7 +11,7 @@
#define USE_UCONTEXT 1
#if defined(__OpenBSD__)
#if defined(__OpenBSD__) || defined(__mips__)
#undef USE_UCONTEXT
#define USE_UCONTEXT 0
#endif
@ -95,6 +95,8 @@ extern void makecontext(ucontext_t*, void(*)(), int, ...);
# define ucontext_t libthread_ucontext_t
# if defined(__i386__)
# include "386-ucontext.h"
# elif defined(__x86_64__)
# include "amd64-ucontext.h"
# else
# include "power-ucontext.h"
# endif
@ -128,6 +130,14 @@ void setmcontext(const mcontext_t*);
#define getcontext(u) getmcontext(&(u)->uc_mcontext)
#endif
#if defined(__mips__)
#include "mips-ucontext.h"
int getmcontext(mcontext_t*);
void setmcontext(const mcontext_t*);
#define setcontext(u) setmcontext(&(u)->uc_mcontext)
#define getcontext(u) getmcontext(&(u)->uc_mcontext)
#endif
typedef struct Context Context;
enum