⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ksr1.h

📁 system C源码 一种替代verilog的语言
💻 H
字号:
/* * QuickThreads -- Threads-building toolkit. * Copyright (c) 1993 by David Keppel * * Permission to use, copy, modify and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice and this notice * appear in all copies.  This software is provided as a * proof-of-concept and for demonstration purposes; there is no * representation about the suitability of this software for any * purpose. */#ifndef QUICKTHREADS_KSR1_H#define QUICKTHREADS_KSR1_H/*    Stack layout:   Registers are saved in strictly low to high order, FPU regs first    (only if qt_block is called), CEU regs second, IPU regs next, with no   padding between the groups.   Callee-save:  f16..f63; c15..c30; i12..i30.   Args passed in i2..i5.   Note: c31 is a private data pointer.  It is not changed on thread   swaps with the assumption that it represents per-processor rather   than per-thread state.   Note: i31 is an instruction count register that is updated by the   context switch routines.  Like c31, it is not changed on context   switches.   This is what we want on startup:   +------		<-- BOS: Bottom of stack (grows down)   | 80 (128 - 48) bytes of padding to a 128-byte boundary   +---   | only   | userf   | t   | u   | qt_start$TXT   | (empty)     	<-- qt.sp   +------		<-- (BOS - 128)   This is why we want this on startup:      A thread begins running when the restore procedure switches thread stacks   and pops a return address off of the top of the new stack (see below   for the reason why we explicitly store qt_start$TXT).  The   block procedure pushes two jump addresses on a thread's stack before   it switches stacks.  The first is the return address for the block   procedure, and the second is a restore address.  The return address   is used to jump back to the thread that has been switched to;  the   restore address is a jump within the block code to restore the registers.   Normally, this is just a jump to the next address.  However, on thread   startup, this is a jump to qt_start$TXT.  (The block procedure stores   the restore address at an offset of 8 bytes from the top of the stack,   which is also the offset at which qt_start$TXT is stored on the stacks   of new threads.  Hence, when the block procedure switches to a new   thread stack, it will initially jump to qt_start$TXT; thereafter,   it jumps to the restore code.)   qt_start$TXT, after it has read the initial data on the new thread's   stack and placed it in registers, pops the initial stack frame   and gives the thread the entire stack to use for execution.   The KSR runtime system has an unusual treatment of pointers to   functions.  From C, taking the `name' of a function yields a   pointer to a _constant block_ and *not* the address of the   function.  The zero'th entry in the constant block is a pointer to   the function.   We have to be careful: the restore procedure expects a return   address on the top of the stack (pointed to by qt.sp).  This is not   a problem when restoring a thread that has run before, since the   block routine would have stored the return address on top of the   stack.  However, when ``faking up'' a thread start (bootstrapping a   thread stack frame), the top of the stack needs to contain a   pointer to the code that will start the thread running.   The pointer to the startup code is *not* `qt_start'.  It is the   word *pointed to* by `qt_start'.  Thus, we dereference `qt_start',   see QUICKTHREADS_ARGS_MD below.   On varargs startup (still unimplemented):   | padding to 128 byte boundary   | varargs		<-- padded to a 128-byte-boundary   +---   | caller's frame, 16 bytes   | 80 bytes of padding (frame padded to a 128-byte boundary)   +---   | cleanup   | vuserf   | startup   | t   +---   | qt_start		<-- qt.sp   +---   Of a suspended thread:   +---   | caller's frame, 16 bytes   | fpu registers 47 regs * 8 bytes/reg 376 bytes   | ceu registers 16 regs * 8 bytes/reg 128 bytes   | ipu registers 19 regs * 8 bytes/reg 152 bytes   |  :   | 80 bytes of padding   |  :   | qt_restore		<-- qt.sp   +---   */#define QUICKTHREADS_STKALIGN	128#define QUICKTHREADS_GROW_DOWNtypedef unsigned long qt_word_t;#define QUICKTHREADS_STKBASE	QUICKTHREADS_STKALIGN#define QUICKTHREADS_VSTKBASE	QUICKTHREADS_STKBASEextern void qt_start(void);/* * See the discussion above for what indexing into a procedure ptr  * does for us (it's lovely, though, isn't it?). * * This assumes that the address of a procedure's code is the * first word in a procedure's constant block.  That's how the manual * says it will be arranged. */#define QUICKTHREADS_ARGS_MD(sp)	(QUICKTHREADS_SPUT (sp, 1, ((qt_word_t *)qt_start)[0]))/*  * The *index* (positive offset) of where to put each value. * See the picture of the stack above that explains the offsets. */#define QUICKTHREADS_ONLY_INDEX	(5)#define QUICKTHREADS_USER_INDEX	(4)#define QUICKTHREADS_ARGT_INDEX	(3)#define QUICKTHREADS_ARGU_INDEX	(2)#define QUICKTHREADS_VARGS_DEFAULT#define QUICKTHREADS_VARGS(sp, nb, vargs, pt, startup, vuserf, cleanup) \      (qt_vargs (sp, nbytes, &vargs, pt, startup, vuserf, cleanup))#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \  ((qt_t *)(((char *)(sp)) - 4*8 - QUICKTHREADS_STKROUNDUP(vabytes)))extern void qt_vstart(void);#define QUICKTHREADS_VARGS_MD1(sp)	(QUICKTHREADS_SPUT (sp, 0, ((qt_word_t *)qt_vstart)[0]))#define QUICKTHREADS_VCLEANUP_INDEX	(4)#define QUICKTHREADS_VUSERF_INDEX		(3)#define QUICKTHREADS_VSTARTUP_INDEX	(2)#define QUICKTHREADS_VARGT_INDEX		(1)#endif /* def QUICKTHREADS_KSR1_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -