From 30a54cd01f46234158839d9a6cf458649587d7e6 Mon Sep 17 00:00:00 2001 From: mini Date: Mon, 16 Sep 2002 19:28:01 +0000 Subject: Add kernel support needed for the KSE-aware libpthread: - Use ucontext_t's to store KSE thread state. - Synthesize state for the UTS upon each upcall, rather than saving and copying a trapframe. - Save and restore FPU state properly in ucontext_t's. - Deliver signals to KSE-aware processes via upcall. - Rename kse mailbox structure fields to be more BSD-like. - Store the UTS's stack in struct proc in a stack_t. Reviewed by: bde, deischen, julian Approved by: -arch --- sys/sys/kse.h | 62 ++++++++++++++++++++++++++++++------------------------ sys/sys/proc.h | 18 ++++++++-------- sys/sys/ucontext.h | 6 +++++- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/sys/sys/kse.h b/sys/sys/kse.h index ac58a6c..9b225bd 100644 --- a/sys/sys/kse.h +++ b/sys/sys/kse.h @@ -32,8 +32,11 @@ #ifndef SYS_KSE_H #define SYS_KSE_H + #include -/* +#include + +/* * This file defines the structures needed for communication between * the userland and the kernel when running a KSE-based threading system. * The only programs that should see this file are the UTS and the kernel. @@ -41,38 +44,41 @@ struct kse_mailbox; typedef void kse_fn_t(struct kse_mailbox *mbx); -/* - * Each userland thread has one of these buried in it's - * Thread control structure somewhere. +/* + * Thread mailbox. + * + * This describes a user thread to the kernel scheduler. */ -struct thread_mailbox -{ - struct thread_mailbox *next_completed; - unsigned int flags; - void *UTS_handle; /* The UTS can use this for anything */ - union kse_td_ctx ctx; /* thread's saved context goes here. */ +struct thread_mailbox { + ucontext_t tm_context; /* User and machine context */ + unsigned int tm_flags; /* Thread flags */ + struct thread_mailbox *tm_next; /* Next thread in list */ + void *tm_udata; /* For use by the UTS */ + int tm_spare[8]; }; -/* - * You need to supply one of these as the argument to the - * kse_new() system call. +/* + * KSE mailbox. + * + * Cummunication path between the UTS and the kernel scheduler specific to + * a single KSE. */ -struct kse_mailbox -{ - kse_fn_t *kmbx_upcall; - char *kmbx_stackbase; - unsigned long int kmbx_stacksize; - struct thread_mailbox *kmbx_current_thread; - struct thread_mailbox *kmbx_completed_threads; - unsigned int kmbx_flags; - void *kmbx_UTS_handle; /* UTS can use this for anything */ +struct kse_mailbox { + struct thread_mailbox *km_curthread; /* Currently running thread */ + struct thread_mailbox *km_completed; /* Threads back from kernel */ + sigset_t km_sigscaught; /* Caught signals */ + unsigned int km_flags; /* KSE flags */ + void *km_func; /* UTS function */ + stack_t km_stack; /* UTS context */ + void *km_udata; /* For use by the UTS */ + int tm_spare[8]; }; -#define KEMBXF_CRITICAL 0x00000001 -struct kse_global_mailbox -{ - unsigned int flags; -}; -#define GMBXF_CRITICAL 0x00000001 +#ifndef _KERNEL +int kse_exit(void); +int kse_wakeup(void); +int kse_new(struct kse_mailbox *, int); +int kse_yield(void); +#endif #endif diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 7e4c1d1..cb0ea5e 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -55,6 +55,7 @@ #else #include #endif +#include #include #include /* Machine-dependent proc substruct. */ @@ -282,7 +283,7 @@ struct thread { LIST_HEAD(, mtx) td_contested; /* (j) Contested locks. */ struct lock_list_entry *td_sleeplocks; /* (k) Held sleep locks. */ int td_intr_nesting_level; /* (k) Interrupt recursion. */ - void *td_mailbox; /* The userland mailbox address. */ + struct thread_mailbox *td_mailbox; /* the userland mailbox address */ struct ucred *td_ucred; /* (k) Reference to credentials. */ void (*td_switchin)(void); /* (k) Switchin special func. */ u_int td_critnest; /* (k) Critical section nest level. */ @@ -421,7 +422,9 @@ struct kse { KES_UNQUEUED, /* in transit */ KES_THREAD /* slaved to thread state */ } ke_state; /* (j) S* process status. */ - void *ke_mailbox; /* the userland mailbox address */ + struct kse_mailbox *ke_mailbox; /* the userland mailbox address */ + stack_t ke_stack; + void *ke_upcall; struct thread *ke_tdspare; /* spare thread for upcalls */ #define ke_endzero ke_dummy @@ -429,9 +432,6 @@ struct kse { u_char ke_dummy; #define ke_endcopy ke_mdstorage - void *ke_upcall; - void *ke_stackbase; - u_long ke_stacksize; void *ke_mdstorage; /* where we store the pcb and frame */ struct pcb *ke_pcb; /* the pcb saved for the upcalls */ struct trapframe *ke_frame; /* the upcall trapframe */ @@ -898,11 +898,8 @@ struct kse *kse_alloc(void); void kse_free(struct kse *td); struct thread *thread_alloc(void); void thread_free(struct thread *td); -int cpu_export_context(struct thread *td); -void cpu_free_kse_mdstorage(struct kse *kse); -void cpu_save_upcall(struct thread *td, struct kse *newkse); -void cpu_set_args(struct thread *, struct kse *); void cpu_set_upcall(struct thread *td, void *pcb); +void cpu_set_upcall_kse(struct thread *td, struct kse *ke); void cpu_thread_exit(struct thread *); void cpu_thread_setup(struct thread *td); void kse_reassign(struct kse *ke); @@ -910,11 +907,14 @@ void kse_link(struct kse *ke, struct ksegrp *kg); void ksegrp_link(struct ksegrp *kg, struct proc *p); int kserunnable(void); void make_kse_runnable(struct kse *ke); +struct thread *signal_upcall(struct proc *p, int sig); void thread_exit(void) __dead2; int thread_export_context(struct thread *td); void thread_link(struct thread *td, struct ksegrp *kg); void thread_reap(void); struct thread *thread_schedule_upcall(struct thread *td, struct kse *ke); +int thread_setcontext(struct thread *td, ucontext_t *uc); +void thread_getcontext(struct thread *td, ucontext_t *uc); int thread_single(int how); #define SINGLE_NO_EXIT 0 /* values for 'how' */ #define SINGLE_EXIT 1 diff --git a/sys/sys/ucontext.h b/sys/sys/ucontext.h index 424e06f..194b63a 100644 --- a/sys/sys/ucontext.h +++ b/sys/sys/ucontext.h @@ -31,6 +31,7 @@ #ifndef _SYS_UCONTEXT_H_ #define _SYS_UCONTEXT_H_ +#include #include typedef struct __ucontext { @@ -47,7 +48,9 @@ typedef struct __ucontext { struct __ucontext *uc_link; stack_t uc_stack; - int __spare__[8]; + int uc_flags; +#define UCF_SWAPPED 0x00000001 /* Used by swapcontext(3). */ + int __spare__[4]; } ucontext_t; #ifndef _KERNEL @@ -57,6 +60,7 @@ __BEGIN_DECLS int getcontext(ucontext_t *); int setcontext(const ucontext_t *); void makecontext(ucontext_t *, void (*)(void), int, ...); +int signalcontext(ucontext_t *, int, __sighandler_t *); int swapcontext(ucontext_t *, const ucontext_t *); __END_DECLS -- cgit v1.1