bradley@uiucdcsm.cs.uiuc.edu (02/04/88)
Many apologies for the delays in getting this out. Here are the modified files we used to build C++ 1.2.1 on our 3/280. We didn't build the scratch compiler. We used cfront on a Multimax that already had a working version of C++ instead. Still, the files that follow may be helpful. The three files that were changed were stdio.h, task.c, and signal.h. There were also some changes to the makefile (SHELL=/bin/sh) and to CC (fixing basename). These should be obvious. One thing we noticed but haven't done anything about: Some special values in math.h, like MAX_FLOAT and HUGE_FLOAT (or something like that), are different in the "native" include file that comes with the Suns than in the file that comes with C++. Since we're not running any numerical applications we haven't worried about fixing these. You may want to look at these. Another observation: Don't change the putc and getc macro definitions in stdio.h! I tried to be clever and change them to match the Sun versions of getc and putc. It didn't work! Remember that the getc and putc macros work with the I/O routines in libC.a, not libc.a. It's OK if they're different. (This cost me a lot of time!) The stdio.h and task.c that are included below were modified by someone in another department here at the U of I. I'm leaving his name out on purpose so that he doesn't get flooded with mail messages (like I have). This doesn't mean that we aren't grateful! David Bradley bradley@a.cs.uiuc.edu Picasso Project -- "Better living through parallel processing." Department of Computer Science University of Illinois at Urbana-Champaign (Where it's snowing like the Dickens now.) #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # signal.h # stdio.h # task.c # This archive created: Wed Feb 3 15:41:38 1988 export PATH; PATH=/bin:$PATH if test -f 'signal.h' then echo shar: will not over-write existing file "'signal.h'" else cat << \SHAR_EOF > 'signal.h' /* @(#)signal.h 1.1 86/07/07 SMI; from UCB 6.7 85/06/08 */ /* * Copyright (c) 1982 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1986 by Sun Microsystems, Inc. */ #ifndef NSIG #define NSIG 32 #define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt */ #define SIGQUIT 3 /* quit */ #define SIGILL 4 /* illegal instruction (not reset when caught) */ #ifdef vax #define ILL_RESAD_FAULT 0x0 /* reserved addressing fault */ #define ILL_PRIVIN_FAULT 0x1 /* privileged instruction fault */ #define ILL_RESOP_FAULT 0x2 /* reserved operand fault */ /* CHME, CHMS, CHMU are not yet given back to users reasonably */ #endif vax #ifdef mc68000 #define ILL_ILLINSTR_FAULT 0x10 /* illegal instruction fault */ #define ILL_PRIVVIO_FAULT 0x20 /* privilege violation fault */ #define ILL_COPROCERR_FAULT 0x34 /* [coprocesser protocol error fault] */ #define ILL_TRAP1_FAULT 0x84 /* trap #1 fault */ #define ILL_TRAP2_FAULT 0x88 /* trap #2 fault */ #define ILL_TRAP3_FAULT 0x8c /* trap #3 fault */ #define ILL_TRAP4_FAULT 0x90 /* trap #4 fault */ #define ILL_TRAP5_FAULT 0x94 /* trap #5 fault */ #define ILL_TRAP6_FAULT 0x98 /* trap #6 fault */ #define ILL_TRAP7_FAULT 0x9c /* trap #7 fault */ #define ILL_TRAP8_FAULT 0xa0 /* trap #8 fault */ #define ILL_TRAP9_FAULT 0xa4 /* trap #9 fault */ #define ILL_TRAP10_FAULT 0xa8 /* trap #10 fault */ #define ILL_TRAP11_FAULT 0xac /* trap #11 fault */ #define ILL_TRAP12_FAULT 0xb0 /* trap #12 fault */ #define ILL_TRAP13_FAULT 0xb4 /* trap #13 fault */ #define ILL_TRAP14_FAULT 0xb8 /* trap #14 fault */ #endif mc68000 #define SIGTRAP 5 /* trace trap (not reset when caught) */ #define SIGIOT 6 /* IOT instruction */ #define SIGEMT 7 /* EMT instruction */ #ifdef mc68000 #define EMT_EMU1010 0x28 /* line 1010 emulator trap */ #define EMT_EMU1111 0x2c /* line 1111 emulator trap */ #endif mc68000 #define SIGFPE 8 /* floating point exception */ #ifdef vax #define FPE_INTOVF_TRAP 0x1 /* integer overflow */ #define FPE_INTDIV_TRAP 0x2 /* integer divide by zero */ #define FPE_FLTOVF_TRAP 0x3 /* floating overflow */ #define FPE_FLTDIV_TRAP 0x4 /* floating/decimal divide by zero */ #define FPE_FLTUND_TRAP 0x5 /* floating underflow */ #define FPE_DECOVF_TRAP 0x6 /* decimal overflow */ #define FPE_SUBRNG_TRAP 0x7 /* subscript out of range */ #define FPE_FLTOVF_FAULT 0x8 /* floating overflow fault */ #define FPE_FLTDIV_FAULT 0x9 /* divide by zero floating fault */ #define FPE_FLTUND_FAULT 0xa /* floating underflow fault */ #endif vax #ifdef mc68000 #define FPE_INTDIV_TRAP 0x14 /* integer divide by zero */ #define FPE_CHKINST_TRAP 0x18 /* CHK [CHK2] instruction */ #define FPE_TRAPV_TRAP 0x1c /* TRAPV [cpTRAPcc TRAPcc] instr */ #define FPE_FLTBSUN_TRAP 0xc0 /* [branch or set on unordered cond] */ #define FPE_FLTINEX_TRAP 0xc4 /* [floating inexact result] */ #define FPE_FLTDIV_TRAP 0xc8 /* [floating divide by zero] */ #define FPE_FLTUND_TRAP 0xcc /* [floating underflow] */ #define FPE_FLTOPERR_TRAP 0xd0 /* [floating operand error] */ #define FPE_FLTOVF_TRAP 0xd4 /* [floating overflow] */ #define FPE_FLTNAN_TRAP 0xd8 /* [floating Not-A-Number] */ #ifdef sun #define FPE_FPA_ENABLE 0x400 /* [FPA not enabled] */ #define FPE_FPA_ERROR 0x404 /* [FPA arithmetic exception] */ #endif sun #endif mc68000 #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #define SIGBUS 10 /* bus error */ #define SIGSEGV 11 /* segmentation violation */ #define SIGSYS 12 /* bad argument to system call */ #define SIGPIPE 13 /* write on a pipe with no one to read it */ #define SIGALRM 14 /* alarm clock */ #define SIGTERM 15 /* software termination signal from kill */ #define SIGURG 16 /* urgent condition on IO channel */ #define SIGSTOP 17 /* sendable stop signal not from tty */ #define SIGTSTP 18 /* stop signal from tty */ #define SIGCONT 19 /* continue a stopped process */ #define SIGCHLD 20 /* to parent on child stop or exit */ #define SIGCLD 20 /* System V name for SIGCHLD */ #define SIGTTIN 21 /* to readers pgrp upon background tty read */ #define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ #define SIGIO 23 /* input/output possible signal */ #define SIGPOLL SIGIO /* System V name for SIGIO */ #define SIGXCPU 24 /* exceeded CPU time limit */ #define SIGXFSZ 25 /* exceeded file size limit */ #define SIGVTALRM 26 /* virtual time alarm */ #define SIGPROF 27 /* profiling time alarm */ #define SIGWINCH 28 /* window changed */ #define SIGLOST 29 /* resource lost (eg, record-lock lost) */ #define SIGUSR1 30 /* user defined signal 1 */ #define SIGUSR2 31 /* user defined signal 2 */ #if 0 // removed to work with /usr/include/CC/signal.h dkb #ifndef KERNEL int (*signal())(); #endif !KERNEL #endif 0 #ifndef LOCORE /* * Signal vector "template" used in sigvec call. */ struct sigvec { int (*sv_handler)(); /* signal handler */ int sv_mask; /* signal mask to apply */ int sv_flags; /* see signal options below */ }; #define SV_ONSTACK 0x0001 /* take signal on signal stack */ #define SV_INTERRUPT 0x0002 /* do not restart system on signal return */ #define SV_RESETHAND 0x0004 /* reset signal handler to SIG_DFL when signal taken */ #define sv_onstack sv_flags /* isn't compatibility wonderful! */ /* * Structure used in sigstack call. */ struct sigstack { char *ss_sp; /* signal stack pointer */ int ss_onstack; /* current status */ }; /* * Information pushed on stack when a signal is delivered. * This is used by the kernel to restore state following * execution of the signal handler. It is also made available * to the handler to allow it to properly restore state if * a non-standard exit is performed. */ struct sigcontext { int sc_onstack; /* sigstack state to restore */ int sc_mask; /* signal mask to restore */ int sc_sp; /* sp to restore */ int sc_pc; /* pc to retore */ int sc_ps; /* psl to restore */ }; #endif !LOCORE #define BADSIG (int (*)())-1 #define SIG_DFL (int (*)())0 #define SIG_IGN (int (*)())1 #ifdef KERNEL #define SIG_CATCH (int (*)())2 #define SIG_HOLD (int (*)())3 #endif KERNEL #endif !NSIG /* * Macro for converting signal number to a mask suitable for sigblock(). */ #define sigmask(m) (1 << ((m)-1)) SHAR_EOF fi # end of overwriting check if test -f 'stdio.h' then echo shar: will not over-write existing file "'stdio.h'" else cat << \SHAR_EOF > 'stdio.h' #ifndef BSD #define BSD #endif /* @(#) stdio.h 1.14 2/16/87 11:02:31 */ /*ident "@(#)cfront:incl/stdio.h 1.14"*/ #ifndef STDIOH #define STDIOH #define BUFSIZ 1024 #define _NFILE 20 # ifndef FILE extern struct _iobuf { #if vax || u3b || u3b2 || u3b5 || mc68k || mc68020 || sun int _cnt; unsigned char *_ptr; #else unsigned char *_ptr; int _cnt; #endif char *_base; # ifdef BSD int _bufsiz; short _flag; # else char _flag; # endif char _file; } _iob[_NFILE]; # endif #define _IOFBF 0000 #define _IOREAD 0001 #define _IOWRT 0002 #define _IONBF 0004 #define _IOMYBUF 0010 #define _IOEOF 0020 #define _IOERR 0040 #define _IOLBF 0100 #define _IORW 0200 #define NULL 0 #define FILE struct _iobuf #define EOF (-1) extern int _flsbuf(unsigned,FILE*); extern int _filbuf(FILE*); #define stdin (&_iob[0]) #define stdout (&_iob[1]) #define stderr (&_iob[2]) #define getc(p) (--(p)->_cnt>=0? *(p)->_ptr++&0377:_filbuf(p)) #define getchar() getc(stdin) #define putc(x,p) (--(p)->_cnt>=0? ((int)(*(p)->_ptr++=(unsigned)(x))):_flsbuf((unsigned)(x),p)) #define putchar(x) putc(x,stdout) #define feof(p) (((p)->_flag&_IOEOF)!=0) #define ferror(p) (((p)->_flag&_IOERR)!=0) #define fileno(p) ((p)->_file) extern FILE* fopen(const char*, const char*); extern FILE* fdopen(int, const char*); extern FILE* freopen(const char*, const char*, FILE*); extern long ftell(const FILE*); extern char* fgets(char*, int, FILE*); #define L_ctermid 9 #define L_cuserid 9 #define P_tmpdir "/tmp/" #define L_tmpnam (sizeof(P_tmpdir) + 15) extern char* gets(char*); extern int puts(const char*); extern int fputs(const char*, FILE*); extern int printf(const char* ...); extern int fprintf(FILE*, const char* ...); extern int sprintf(char*, const char* ...); extern int scanf(const char* ...); extern int fscanf(FILE*, const char* ...); extern int sscanf(char*, const char* ...); extern int fread(char*, unsigned int, int, FILE*); extern int fwrite(const char*, unsigned int, int, FILE*); extern int fclose(FILE*); extern int fflush(FILE*); extern void clearerr(FILE*); extern int fseek(FILE*, long, int); extern void rewind(FILE*); extern int getw(FILE*); extern int fgetc(FILE*); extern FILE* popen(const char*, const char*); extern int pclose(FILE*); extern int putw(int, FILE*); extern int fputc(int, FILE*); extern void setbuf(FILE*, char*); extern int ungetc(int, FILE*); extern void exit(int); extern int abort(...); extern int atoi(const char*); extern double atof(const char*); extern long atol(const char*); #define _bufend(p) _bufendtab[(p)->_file] #define _bufsiz(p) (_bufend(p) - (p)->_base) extern FILE *tmpfile (); extern char *ctermid(char*), *cuserid(char*), *tempnam(char*, char*), *tmpnam(char*); extern void perror (const char*); extern int errno; extern char* sys_errlist[]; extern int sys_nerr; extern unsigned char *_bufendtab[]; #endif /* STDIOH */ #ifdef ZZZ #define BUFSIZ 1024 #define _SBFSIZ 8 extern struct _iobuf { int _cnt; unsigned char *_ptr; unsigned char *_base; int _bufsiz; short _flag; char _file; /* should be short */ } _iob[]; #define getc(p) (--(p)->_cnt>=0? ((int)*(p)->_ptr++):_filbuf(p)) #define getchar() getc(stdin) #define putc(x,p) (--(p)->_cnt>=0? (int)(*(p)->_ptr++=(unsigned char)(x)):_flsbuf((unsigned char)(x),p)) #define putchar(x) putc((x),stdout) #endif SHAR_EOF fi # end of overwriting check if test -f 'task.c' then echo shar: will not over-write existing file "'task.c'" else cat << \SHAR_EOF > 'task.c' /*ident "@(#)cfront:lib/task/task.c 1.6" */ #include "task.h" /* macros giving the addresses of the stack frame pointer and the program counter of the caller of the current function given the first local variable TOP points to the top of the current stack frame given the last local variable */ #ifdef pdp11 // STACK GROWS DOWN #define FP(p) ( (int*)(&p+4) ) #define AP() 0 /* unnecessary on pdp11 */ #define OLD_FP(fp) (*fp) #define TOP(var9) (&var9) #define COPY_STACK(f,c,t) while (c--) *t-- = *f-- #define ACTIVE_STK_SZ(b,t) b - t + 1 /* size of active stack */ #define STACK_BASE(b,s) b + s - 1 #define SAVED_AREA(b,s) b - s + 1 #define FIX_FRAME(x)\ OLD_FP(t_framep) = int(de_fp - x) #define SETTRAP() t_trap = *(t_basep - t_stacksize + 1) #define CHECKTRAP() if (t_trap != *(t_basep-t_stacksize+1))\ task_error(E_STACK,0) #endif #ifdef sun // STACK GROWS DOWN #define FP(p) ( (int*)(&p+1) ) #define AP() 0 /* unnecessary on sun */ #define OLD_AP(fp) 0 /* unnecessary on sun */ #define OLD_FP(fp) (*fp) #define TOP(p) ( (int *) (&p) ) #define COPY_STACK(f,c,t) while (c--) *t-- = *f-- #define ACTIVE_STK_SZ(b,t) b - t + 1 /* size of active stack */ #define STACK_BASE(b,s) b + s - 1 #define SAVED_AREA(b,s) b - s + 1 #define FIX_FRAME(x)\ OLD_FP(t_framep) = int(de_fp - x) #define SETTRAP() t_trap = *(t_basep - t_stacksize + 1) #define CHECKTRAP() if (t_trap != *(t_basep-t_stacksize+1))\ task_error(E_STACK,0) #endif #ifdef vax // STACK GROWS DOWN #define FP(p) ( (int*)(&p+1) ) #define AP() 0 /* unnecessary on vax */ #define OLD_AP(fp) (*(fp+2)) #define OLD_FP(fp) (*(fp+3)) #define TOP(p) top(&p) extern int * top(...); #define COPY_STACK(f,c,t) while (c--) *t-- = *f-- #define ACTIVE_STK_SZ(b,t) b - t + 1 /* size of active stack */ #define STACK_BASE(b,s) b + s - 1 #define SAVED_AREA(b,s) b - s + 1 #define FIX_FRAME(x)\ OLD_AP(t_framep) = int(de_ap - x);\ OLD_FP(t_framep) = int(de_fp - x) #define SETTRAP() t_trap = *(t_basep - t_stacksize + 1) #define CHECKTRAP() if (t_trap != *(t_basep-t_stacksize+1))\ task_error(E_STACK,0) #endif #if u3b | u3b5 | u3b2 | u3b15 // STACK GROWS UP #define FP(p) ( (int*)&p ) extern int * AP(); /* AP of current frame */ #define TOP(x) (int*)( (int*)&x + 1 ) #ifdef u3b asm(" .text"); asm(" .globl AP"); asm(" .align 4"); asm("AP:"); asm(" save &0"); asm(" movw -48(%fp),%r0 # caller's ap"); asm(" ret &0"); #define OLD_FP(fp) ( *( (int*)fp - 11 ) ) #define OLD_AP(fp) ( *( (int*)fp - 12 ) ) #else asm(" .text"); asm(" .globl AP"); asm(" .align 4"); asm("AP:"); asm(" save &0"); asm(" movw -32(%fp),%r0 # caller's ap"); asm(" ret &0"); #define OLD_FP(fp) ( *( (int*)fp - 7 ) ) #define OLD_AP(fp) ( *( (int*)fp - 8 ) ) #endif #define COPY_STACK(f,c,t) while (c--) *t++ = *f++ #define ACTIVE_STK_SZ(b,t) t - b + 1 /* size of active stack */ #define STACK_BASE(b,s) b #define SAVED_AREA(b,s) b #define FIX_FRAME(x)\ t_ap = AP() - x;\ OLD_AP(t_framep) = int(de_ap - x);\ OLD_FP(t_framep) = int(de_fp - x) #define SETTRAP() t_trap = *(t_basep + t_stacksize - 1) #define CHECKTRAP() if (t_trap != *(t_basep+t_stacksize-1))\ task_error(E_STACK,0) #endif // ---- END OF MACROS ---- int _hwm = 1; class team { friend task; int no_of_tasks; task* got_stack; int* stack; team(task*, int = 0); }; team.team(task* t, int stacksize) { stacksize += sizeof(team); // alloc team and stack together this = (team*)new int[stacksize]; while (this == 0) task_error(E_STORE,0); stack = (int*)this + sizeof(team); no_of_tasks = 1; got_stack = t; } void usemainstack() /* fudge to allow simple stack overflow check */ { register v[SIZE+100]; if (_hwm) for (register i=0;i<SIZE+100;i++) v[i] = UNTOUCHED; else v[0] = 0; } void copy_stack(register* f, register c, register* t) /* copy c words down from f to t do NOT attempt to copy "copy_stack"'s own stackframe */ { DB((" copying( %x, %x, %x )\n", f, c, t)); COPY_STACK(f,c,t); DB((" copied\n")); } #define ABSV(x) ( (x) > 0 ? (x) : -(x) ) task.task(char* name, int mode, int stacksize) : (TASK) /* executed in the task creating a new task - thistask. 1: put thistask at head of scheduler queue, 2: create new task 3: transfer execution to new task derived::derived can never return - its return link is destroyed if thistask==0 then we are executing on main()'s stack and should turn it into the "main" task */ { int* p; int* ta_fp = (int*)FP(p); int* de_fp = (int*)OLD_FP(ta_fp); int* de_ap; de_ap = (int*)OLD_AP(ta_fp); int* pa_fp = (int*)OLD_FP(de_fp); int x; DB(("%x->task::task( %s, %x, %x )\n", this,name,mode,stacksize)); t_name = name; t_mode = (mode) ? mode : DEDICATED; t_stacksize = (stacksize) ? stacksize : SIZE; t_size = 0; /* avoid stack copy at initial restore */ t_alert = 0; s_state = RUNNING; t_next = task_chain; task_chain = this; th = this; /* fudged return value -- "returned" from swap */ switch ((int)thistask) { case 0: /* initialize task system by creating "main" task */ thistask = (task*) 1; DB((" thistask = new task(\"main\")\n")); thistask = new task("main"); break; case 1: /* create "main" task */ usemainstack(); /* ensure that store is allocated */ t_basep = (int*)OLD_FP(pa_fp); /* fudge, what if main is already deeply nested */ t_team = new team(this); /* don't allocate stack */ t_team->no_of_tasks = 2; /* never deallocate */ return; } thistask->th = this; /* return pointer to "child" */ thistask->t_framep = de_fp; /* return to caller of derived ctor */ thistask->t_ap = de_ap; thistask->insert(0,this); switch (t_mode) { case DEDICATED: t_team = new team(this,t_stacksize); t_basep = STACK_BASE(t_team->stack, t_stacksize); if (_hwm) for (x=0; x<t_stacksize; x++) t_team->stack[x] = UNTOUCHED; thistask = this; DB(("%x->task::task -- ta_fp = %x\n",this,ta_fp)); DB(("%x->task::task -- ta_ap = %x\n",this,AP())); x = ACTIVE_STK_SZ(pa_fp, TOP(x)); copy_stack(pa_fp, x, t_basep); x = pa_fp - t_basep; /* distance from old stack to new */ t_framep = ta_fp - x; /* fp on new frame */ /* now doctor the new frame */ DB((" OFP(t_framep),de_fp == %x,%x\n",OLD_FP(t_framep),de_fp)); DB((" OAP(t_framep),de_ap == %x,%x\n",OLD_AP(t_framep),de_ap)); FIX_FRAME(x); restore(); case SHARED: thistask->t_mode = SHARED; /* you cannot share on your own */ t_basep = pa_fp; t_team = thistask->t_team; t_team->no_of_tasks++; t_framep = ta_fp; t_ap = AP(); if (mode==0 && stacksize==0) t_stacksize = thistask->t_stacksize - ABSV(thistask->t_basep - t_basep); thistask = this; SETTRAP(); // normally done in restore() return; default: task_error(E_TASKMODE,this); } } void task.save() /* save task's state so that ``restore'' can resume it later by returning from the function which called "save" - typically the scheduler */ { int* p = (int*)FP(p); DB(("%x->task::save()\n",this)); t_framep = (int*)OLD_FP(p); t_ap = (int*)OLD_AP(p); CHECKTRAP(); if (t_mode == SHARED) { register int sz; t_size = sz = ACTIVE_STK_SZ(t_basep, TOP(p)); p = new int[sz]; while (p == 0) task_error(E_STORE,0); t_savearea = STACK_BASE(p, sz); copy_stack(t_basep,sz,t_savearea); } } extern int rr2,rr3,rr4; int rr2,rr3,rr4; swap(task*); sswap(task*); void task.restore() /* make "this" task run after suspension by returning from the frame denoted by "t_framep" the key function "swap" is written in assembly code, it returns from the function which "save"d the task - typically the scheduler "sswap" copies the stack back from the save area before "swap"ing arguments to "sswap" are passed in rr2,rr3,rr4 to avoid overwriting them it is equivallent to "copystack" followed by "swap". */ { register sz; SETTRAP(); DB(("%x->task::restore()\n",this)); if ((t_mode == SHARED) && (sz=t_size)){ register* p = SAVED_AREA(t_savearea, sz); // get ptr for delete register x = (this != t_team->got_stack); t_team->got_stack = this; if (x) { DB((" p = x%x\n", p)); DB((" t_savearea = x%x\n", t_savearea)); DB((" sz = x%x\n", sz)); DB((" t_basep = x%x\n", t_basep)); delete p; rr4 = (int) t_savearea; rr3 = sz; rr2 = (int) t_basep; sswap(this); } else swap(this); } else swap(this); } void task.cancel(int val) /* TERMINATE and free stack space */ { DB(("%x->task::cancel( %x )\n",this,val)); sched::cancel(val); if (_hwm) t_size = curr_hwm(); if (t_team->no_of_tasks-- == 1) delete t_team; } task.~task() /* free stack space and remove task from task chain */ { DB(("%x->task::~task()\n",this)); if (s_state != TERMINATED) task_error(E_TASKDEL,this); if (this == task_chain) task_chain = t_next; else { register task* t; register task* tt; for (t=task_chain; tt=t->t_next; t=tt) if (tt == this) { t->t_next = t_next; break; } } if (this == thistask) { delete (int*) thistask; /* fudge: free(_that) */ thistask = 0; schedule(); } } void task.resultis(int val) { DB(("%x->task::resultis( %x )\n",this,val)); cancel(val); if (this == thistask) schedule(); } void task.sleep() { DB(("%x->task::sleep()\n",this)); if (s_state == RUNNING) remove(); if (this == thistask) schedule(); } void task.delay(int d) { DB(("%x->task::delay( %x )\n",this,d)); insert(d,this); if (thistask == this) schedule(); } int task.preempt() { DB(("%x->task::preempt()\n",this)); if (s_state == RUNNING) { remove(); return s_time-clock; } else { task_error(E_TASKPRE,this); return 0; } } char* state_string(int s) { switch (s) { case IDLE: return "IDLE"; case TERMINATED: return "TERMINATED"; case RUNNING: return "RUNNING"; default: return 0; } } char* mode_string(int m) { switch(m) { case SHARED: return "SHARED"; case DEDICATED: return "DEDICATED"; default: return 0; } } void task.print(int n) /* ``n'' values: CHAIN,VERBOSE,STACK */ { char* ss = state_string(s_state); char* ns = (t_name) ? t_name : ""; printf("task %s ",ns); if (this == thistask) printf("(is thistask):\n"); else if (ss) printf("(%s):\n",ss); else printf("(state==%d CORRUPTED):\n",s_state); if (n&VERBOSE) { int res = (s_state==TERMINATED) ? (int) s_time : 0; char* ms = mode_string(t_mode); if (ms == 0) ms = "CORRUPTED"; printf("\tthis==x%x mode=%s alert=x%x next=x%x result=%d\n", this,ms,t_alert,t_next,res); } if (n&STACK) { printf("\tstack: "); if (s_state == TERMINATED) { if (_hwm) printf("hwm=x%x",t_size); printf(" deleted\n"); } else { int b = (int) t_basep; int x = ((this==thistask) || t_mode==DEDICATED) ? ACTIVE_STK_SZ( b, (int)t_framep ) : t_size; printf("max=%d current=%d",t_stacksize,x); if (_hwm) printf(" hwm=x%x",curr_hwm()); printf(" t_basep=x%x, t_framep=x%x, t_size=x%x\n", b,t_framep,t_size); } } if (n&CHAIN) { if (t_next) t_next->print(n); } } int task.curr_hwm() { int* b = t_basep; int i; for (i=t_stacksize-1; 0<=i && *(b-i)==UNTOUCHED; i--) ; return i; } int task.waitlist(object* a) { return waitvec(&a); } int task.waitvec(object* * v) /* first determine if it is necessary to sleep(), return hint: who caused return */ { int i = 0; int r; object* ob; while (ob = v[i++]) { t_alert = ob; switch (ob->o_type) { case TASK: case TIMER: if (((sched*)ob)->s_state == TERMINATED) goto ex; break; case QHEAD: if (((qhead*)ob)->rdcount()) goto ex; break; case QTAIL: if (((qtail*)ob)->rdspace()) goto ex; break; } ob->remember(this); } if (i==2 && v[0]==(object*)thistask) task_error(E_WAIT,0); sleep(); ex: i = 0; while (ob = v[i++]) { ob->forget(this); if (ob == t_alert) r = i-1; } return r; } SHAR_EOF fi # end of overwriting check # End of shell archive exit 0