Article View: comp.sys.transputer
Article #1101Unix Occam Compiler
From: Terry Torkelson
Date: Wed, 14 Nov 1990 19:39
Date: Wed, 14 Nov 1990 19:39
3113 lines
60809 bytes
60809 bytes
----------sim.shar----------
#! /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:
# sim
# This archive created: Thu Apr 19 16:54:29 1990
export PATH; PATH=/bin:$PATH
if test ! -d 'sim'
then
mkdir 'sim'
fi
cd 'sim'
if test ! -d 'h'
then
mkdir 'h'
fi
cd 'h'
if test -f 'trace.h'
then
echo shar: will not over-write existing file "'trace.h'"
else
cat << \SHAR_EOF > 'trace.h'
/*
* Occam kernel tracer definitions.
*/
extern int tracer; /* tracing flags */
extern char *BlockStat(), *Pinfo();
/* tracing options: */
#define TRACE_CSW 0x1 /* trace context switches */
#define TRACE_FORK 0x2 /* trace forks */
#define TRACE_BLOCK 0x4 /* trace blocks/unblocks */
#define TRACE_IO 0x10 /* trace i/o events. */
#define TRACE_MOREIO 0x20 /* trace more i/o events */
#define TRACE_ALLIO (TRACE_IO:TRACE_MOREIO) /* trace all i/o
: operations */
#define TRACE_ALL (0xffff)
FILE *tracef;
/*
: TRACE(flags, (fmt, args...)):
: flags - trace flags for which this trace message is applied.
: fmt, args - tracing message. passed to printf.
*/
#define TRACE(flg, args) if(tracer&(flg)) pflg(flg), ptrace args
#define NTRACE(flg, args) if(tracer&(flg)) sflg(flg), ptrace args
SHAR_EOF
fi # end of overwriting check
if test -f 'vmsio.h'
then
echo shar: will not over-write existing file "'vmsio.h'"
else
cat << \SHAR_EOF > 'vmsio.h'
/*
: $Header: vmsio.h,v 3.1 86/11/01 15:45:09 gil Exp $
: VMS-Occam Compatible Channel definitions.
*/
#define _InF(v) (v+3)
#define _OutF(v) (v+11)
/* Channel Numbers: */
#define C_Parameters 0
#define C_Screen 1
#define C_Keyboard 2
#define C_Filein0 _InF(0)
#define C_Filein1 _InF(1)
#define C_Filein2 _InF(2)
#define C_Filein3 _InF(3)
#define C_Filein4 _InF(4)
#define C_Filein5 _InF(5)
#define C_Filein6 _InF(6)
#define C_Filein7 _InF(7)
#define C_Fileout0 _OutF(0)
#define C_Fileout1 _OutF(1)
#define C_Fileout2 _OutF(2)
#define C_Fileout3 _OutF(3)
#define C_Fileout4 _OutF(4)
#define C_Fileout5 _OutF(5)
#define C_Fileout6 _OutF(6)
#define C_Fileout7 _OutF(7)
#define V_NFILES 8
#define WORDSIZE 4
#define IsInf(f) ((f) < _OutF(0) && (f) >= _InF(0))
#define IsOutf(f) ((f) >= _OutF(0))
#define VFile(f) (((f) < C_Filein0) ? &StdFile[f] : \
&VmsFile[IsInf(f) ? ((f) - C_Filein0) : ((f) - C_Fileout0)])
struct vms_file {
int vms_message;
enum vstat { NORMAL, FILENAME, ARGSTR } vms_stat;
FILE *vms_fp;
char *vms_name;
} VmsFile[V_NFILES], StdFile[3];
typedef struct vms_file VmsChan;
/* Control Values */
#define V_ClosedOK -1
#define V_CloseFile -2
#define V_EndBuffer -3
#define V_EndFile -4
#define V_EndName -5
#define V_EndParameterString -6
#define V_EndRecord -7
#define V_NextRecord -9
#define V_OpenedOK -10
#define V_OpenForRead -11
#define V_OpenForWrite -12
/* Error Values */
#define E_FileNameTooLong 0x80000000
#define E_InputFileNotOpened 0x80000001
#define E_OutputFileNotCreated 0x80000002
#define E_InputRecordTooLong 0x80000004
#define E_ReadFailed 0x80000008
#define E_OutputRecordTooLong 0x80000010
#define E_WriteFailed 0x80000020
#define E_CloseFailed 0x80000040
SHAR_EOF
fi # end of overwriting check
if test -f 'chan.h'
then
echo shar: will not over-write existing file "'chan.h'"
else
cat << \SHAR_EOF > 'chan.h'
#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) > (b) ? (a) : (b))
typedef struct {
int io_len;
char *io_data;
} IoVec;
typedef struct ioblock {
IoVec *b_data;
int b_ndata;
int b_dind; /* index of data array; used also for flags */
#define BD_FAFTER -1 /* if 'after' operation on the time channel */
Process *b_proc;
int b_id;
struct ioblock *b_next;
} IoBlock;
typedef struct channel {
int ch_flags;
int ch_siz; /* for buffered channels: sizeof buffer */
IoBlock ch_read; /* read-requests' queue */
IoBlock ch_write; /* write-requests' queue */
#if (defined(S_SYS) :: defined(S_VMS))
int ch_fd; /* file descriptor for special channels */
#endif /* S_SYS :: S_VMS */
struct channel *ch_nxt;
} Channel;
#ifdef S_SYS
# define CH_SYS 01
# define CH_DEV 04
# define IsSpecial(ch) ((ch)->ch_flags & CH_SYS)
# define IsSpecialDevice(ch) ((ch)->ch_flags & CH_DEV)
#endif S_SYS
#ifdef S_VMS
# define CH_VMS 02
# define IsVms(ch) ((ch)->ch_flags & CH_VMS)
#endif S_VMS
#define CH_TIME 08
#define IsTime(ch) ((ch)->ch_flags & CH_TIME)
#define chanof(id) (&chans[id])
#define chidof(ch) (ch - chans)
#define MAX_CHANS 512
extern Channel chans[];
extern Channel *free_chans;
#define F_AFTER 1
extern int time_ch;
#define new(type) (struct type *)calloc(1, sizeof(struct type))
SHAR_EOF
fi # end of overwriting check
if test -f 'conf.h'
then
echo shar: will not over-write existing file "'conf.h'"
else
cat << \SHAR_EOF > 'conf.h'
/* $Header: conf.h,v 3.3 86/11/04 09:56:28 gil Exp $ */
/*
* This is a configuration file for the OCCAM runtime library.
* It contains a few parameters that determine if certain options will be
* supported by the library.
* See the user manual for detailed description of these options.
* When noted, the compiler should be configured to support the option in the
* language syntax. This is done by setting the options in the compiler's
* configuration file, ../h/conf.h
*
* The options are:
*/
/* S_SYS: include the code for special system channels. With this option
* set the system will support actions on UNIX files through special channels.
*/
#define S_SYS
/* S_VMS: include the code for special VMS channels - these are special system
* channels that conform to the system channels protocol of the INMOS VAX/VMS
* version of OCCAM.
* NOTE: Should be set in the compiler as well.
*/
/* #define S_VMS */
/* BUFF_CHAN: include the code for buffered channels.
* If you don't intend to use buffered channels switch it off for better
* performance.
* NOTE: Should be set in the compiler as well.
*/
#define BUFF_CHANS
SHAR_EOF
fi # end of overwriting check
if test -f 'process.h.bak'
then
echo shar: will not over-write existing file "'process.h.bak'"
else
cat << \SHAR_EOF > 'process.h.bak'
#include <sys/types.h>
#ifdef vax
typedef struct {
int r2, r3, r4, r5, r6, r7, r8, r9, r10;
/* general purpose registers */
caddr_t st_dp; /* display pointer (occam ext. r11) */
caddr_t st_ap; /* argument pointer */
caddr_t st_fp; /* frame pointer */
caddr_t st_sp; /* stack pointer */
caddr_t st_pc; /* program counter */
} SavedData;
#else tahoe
typedef struct {
int r2, r3, r4, r5, r6, r7, r8, r9, r10, r11;
caddr_t st_dp; /* display pointer (r12) */
caddr_t st_fp;
caddr_t st_sp;
caddr_t st_pc;
} SavedData;
#endif
typedef struct {
int s_size;
caddr_t s_bottom;
} Stack;
#ifdef vax
#define DISPSIZE (8*2*4) /* Display contains now 8 levels */
#else tahoe
#define DISPSIZE (8*4) /* Display contains now 8 levels */
#endif
#define COUNTSIZE 4 /* commands counter */
#define topof(s) ((s).s_bottom + (s).s_size - (DISPSIZE + COUNTSIZE))
#define dispof(s) ((s).s_bottom + (s).s_size - COUNTSIZE)
#define bdispof(s) ((s).s_bottom + (s).s_size - (DISPSIZE + COUNTSIZE))
#define timeof(s) ((s).s_bottom + (s).s_size - COUNTSIZE)
#define realtop(s) ((s).s_bottom + (s).s_size)
typedef struct {
int pi_sontime; /* maximum sons' parallel time */
int pi_time;
} Sinfo;
typedef struct process {
int p_pid;
int p_ppid;
struct process *p_parent;
int p_nsons;
int p_nzomb;
Sinfo p_info;
#define p_time p_info.pi_time
#define p_sontime p_info.pi_sontime
int p_flags;
int p_eventid; /* unique id for io events */
int p_chid; /* for select: channel on which io is done */
enum pstat { BLOCK_CHILD, BLOCK_IO, RUNNING } p_stat;
struct process *p_nxt,
*p_prv;
SavedData p_save;
int p_kmode; /* should be in saved data */
Stack p_stack;
Stack p_curstack;
} Process;
#define PF_ZOMB 1
#define NPROC 256
/* definitions for random pickings. recommended that R == NPROC */
#define R 256.0
#define MASKR 0xff
#define STACK_SIZE (8*1024) /* Default stack size = 8k */
#define nproc NPROC
Process *runq, *waitq, *freeq, proctable[NPROC];
extern Process *proc;
extern int kmode;
#define Kmode_On kmode++
#define Kmode_Off kmode--
extern int time_ch;
extern int CommandsTime;
extern int IdleTime;
#include "trace.h"
SHAR_EOF
fi # end of overwriting check
if test -f 'process.h'
then
echo shar: will not over-write existing file "'process.h'"
else
cat << \SHAR_EOF > 'process.h'
#include <sys/types.h>
#ifdef vax
typedef struct {
int r2, r3, r4, r5, r6, r7, r8, r9, r10;
/* general purpose registers */
caddr_t st_dp; /* display pointer (occam ext. r11) */
caddr_t st_ap; /* argument pointer */
caddr_t st_fp; /* frame pointer */
caddr_t st_sp; /* stack pointer */
caddr_t st_pc; /* program counter */
} SavedData;
#else tahoe
typedef struct {
int r2, r3, r4, r5, r6, r7, r8, r9, r10, r11;
caddr_t st_dp; /* display pointer (r12) */
caddr_t st_fp;
caddr_t st_sp;
caddr_t st_pc;
} SavedData;
#endif
typedef struct {
int s_size;
caddr_t s_bottom;
} Stack;
#define SMASK (char)0xbc
#define StackMask(p) ((p) == &proctable[0] :: \
(p)->p_stack.s_bottom[0] == SMASK)
#ifdef vax
#define DISPSIZE (8*2*4) /* Display contains now 8 levels */
#else tahoe
#define DISPSIZE (8*4) /* Display contains now 8 levels */
#endif
#define COUNTSIZE 4 /* commands counter */
#define topof(s) ((s).s_bottom + (s).s_size - (DISPSIZE + COUNTSIZE))
#define dispof(s) ((s).s_bottom + (s).s_size - COUNTSIZE)
#define bdispof(s) ((s).s_bottom + (s).s_size - (DISPSIZE + COUNTSIZE))
#define timeof(s) ((s).s_bottom + (s).s_size - COUNTSIZE)
#define realtop(s) ((s).s_bottom + (s).s_size)
typedef struct {
int pi_sontime; /* maximum sons' parallel time */
int pi_time;
} Sinfo;
typedef struct process {
int p_pid;
int p_ppid;
struct process *p_parent;
int p_nsons;
int p_nzomb;
Sinfo p_info;
#define p_time p_info.pi_time
#define p_sontime p_info.pi_sontime
int p_flags;
int p_eventid; /* unique id for io events */
int p_chid; /* for select: channel on which io is done */
enum pstat { BLOCK_CHILD, BLOCK_IO, RUNNING } p_stat;
struct process *p_nxt,
*p_prv;
SavedData p_save;
int p_kmode; /* should be in saved data */
Stack p_stack;
Stack p_curstack;
} Process;
#define PF_ZOMB 1
#define NPROC 256
/* definitions for random pickings. recommended that R == NPROC */
#define R 256.0
#define MASKR 0xff
#define STACK_SIZE (8*1024) /* Default stack size = 8k */
#define nproc NPROC
Process *runq, *waitq, *freeq, proctable[NPROC];
extern Process *proc;
extern int kmode;
#define Kmode_On kmode++
#define Kmode_Off kmode--
extern int time_ch;
extern int CommandsTime;
extern int IdleTime;
#include "trace.h"
SHAR_EOF
fi # end of overwriting check
cd ..
if test -f 'ext.c'
then
echo shar: will not over-write existing file "'ext.c'"
else
cat << \SHAR_EOF > 'ext.c'
static char rcsid[] = "$Header: ext.c,v 3.3 86/11/03 12:34:59 gil Exp $";
/*
* $Log: ext.c,v $
* Revision 3.3 86/11/03 12:34:59 gil
* buffered channels and special channels are wrapped within 'ifdefs' for
* flexible configuration.
*
* Revision 3.2 86/11/02 09:09:27 gil
* somehow the buffered-cahnnels version got in the way as revision 3.1, BEWARE.
*
* Revision 2.1 86/10/30 18:14:52 gil
* This version was submitted for the project. It is free of all major bugs.
*
* Revision 1.1 86/01/04 14:48:59 gil
* Initial revision
*
*/
#include <stdio.h>
#include "trace.h"
chtabopen(tab, siz, nel)
register int *tab;
{
TRACE(TRACE_IO, ("open channel table at 0x%x - %d", tab, nel));
while (nel--)
*tab++ = chopen(siz);
}
chtabclose(tab, nel)
register int *tab;
{
TRACE(TRACE_IO, ("close channel table at 0x%x - %d", tab, nel));
while(nel--)
chclose(*tab++);
}
int dflag;
#define debugfp stderr
/*VARARGS1*/
debug(fmt, a1, a2, a3, a4, a5, a6)
char *fmt;
{
if(dflag)
fprintf(debugfp, fmt, a1, a2, a3, a4, a5, a6);
}
bcopy(from, to, len)
register int *from, *to;
register len;
{
len >>= 2;
while(len--)
*to++ = *from++;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'machdep.s'
then
echo shar: will not over-write existing file "'machdep.s'"
else
cat << \SHAR_EOF > 'machdep.s'
.globl _SetJmp # the _Setjmp subroutine in VAX
# became _setjmp procedure for TAHOE
_SetJmp:
.word 0x0
movl 4(fp),r1
storer $0x1ffc,(r1)
addl2 $44,r1
movl (fp),(r1)
addl2 $4,r1
movab 8(fp),(r1)
addl2 $4,r1
movl -8(fp),(r1)
clrl r0
ret
.globl _LongJmp # the _Longjmp subroutine in VAX
# became _longjmp procedure for TAHOE
_LongJmp:
.word 0x0000
movl 4(fp),r1
loadr $0x3ffc,(r1)
addl2 $48,r1
# movl (r2),r1
movl (r1),r0
addl2 $4,r1
# movab (sp),r0
# cmpl r1,r0 # must be a pop
# bgequ lj2
# pushab lj1
# callf $8,_panic
lj2:
movl r0,sp
movl $1,r0
jmp *(r1)
lj1: .asciz "longjmp"
SHAR_EOF
fi # end of overwriting check
if test -f 'chq.c'
then
echo shar: will not over-write existing file "'chq.c'"
else
cat << \SHAR_EOF > 'chq.c'
/* $Header: chq..c,v 3.3 86/11/03 12:34:56 gil Exp $ */
/*
* $Log: chq.c,v $
* Revision 3.3 86/11/03 12:34:56 gil
* buffered channels and special channels are wrapped within 'ifdefs' for
* flexible configuration.
*
* Revision 3.2 86/11/03 11:08:21 gil
* this version supports buffered channel.
*
* Revision 3.1 86/11/01 15:42:53 gil
* *** empty log message ***
*
*/
#include <stdio.h>
#include "conf.h"
#include "process.h"
#include "chan.h"
IO(ch, tm)
Channel *ch;
int tm;
{
if (IsTime(ch)) {
debug("[%d] read time\n",
ch->ch_read.b_next->b_proc - proctable);
tread(ch, tm);
#ifdef S_VMS
} else if (IsVms(ch)) {
debug("(%d) i/o in vms channel\n", chidof(ch));
VmsIO(ch, tm);
#endif S_VMS
#ifdef S_SYS
} else if (IsSpecial(ch)) { /* this is s UNIX channel */
debug("(%d) i/o in sys channel\n", chidof(ch));
SysIO(ch, tm);
#endif S_SYS
} else
IoMove(ch, tm);
}
IoMove(ch, tm)
Channel *ch;
int tm;
{
IoBlock *rblk, *wblk;
register ri, wi;
register i, n;
int len;
rblk = ch->ch_read.b_next;
wblk = ch->ch_write.b_next;
if (rblk->b_ndata != wblk->b_ndata)
panic("noncompatible receive-send request on channel\n");
n = rblk->b_ndata;
for (i = 0; i < n; i++, ri++, wi++) {
if (rblk->b_data[i].io_len != wblk->b_data[i].io_len)
panic("noncompatible sizes in receive-send\n");
len = rblk->b_data[i].io_len;
NTRACE(TRACE_IO,
("[%d] sent %d bytes from %s to %s", chidof(ch), len,
Pinfo(wblk->b_proc), Pinfo(rblk->b_proc)));
bcopy(wblk->b_data[i].io_data,rblk->b_data[i].io_data, len);
}
ReadDone(ch, tm);
WriteDone(ch, tm);
}
#ifdef S_SYS
SysIO(ch, tm)
Channel *ch;
{
IoBlock *rblk, *wblk;
rblk = ch->ch_read.b_next;
wblk = ch->ch_write.b_next;
if (!rblk)
SysWrite(ch, tm);
else if (!wblk)
SysRead(ch, tm);
else if (rblk->b_proc->p_time < wblk->b_proc->p_time)
SysRead(ch, tm);
else
SysWrite(ch, tm);
}
#endif S_SYS
#ifdef S_VMS
VmsIO(ch, tm)
Channel *ch;
{
IoBlock *rblk, *wblk;
rblk = ch->ch_read.b_next;
wblk = ch->ch_write.b_next;
if (!rblk)
VmsWrite(ch, tm);
else if (!wblk)
VmsRead(ch, tm);
else if (rblk->b_proc->p_time < wblk->b_proc->p_time)
VmsRead(ch, tm);
else
VmsWrite(ch, tm);
}
#endif S_VMS
/* EnterRequest:
* Enter the read/write request into the channel's read/write queue,
*/
EnterRequest(io_list, flags, len, arg_iov, id)
IoBlock *io_list;
IoVec *arg_iov;
{
register IoBlock *blk;
register IoBlock *iob;
register IoBlock *ip;
register i;
blk = new(ioblock);
for (iob = io_list; iob->b_next; iob = iob->b_next)
;
blk->b_next = iob->b_next;
iob->b_next = blk;
blk->b_ndata = len;
blk->b_proc = proc;
blk->b_id = id;
blk->b_data = (IoVec *)calloc(len, sizeof(IoVec));
for(i = 0; i < len; i++)
blk->b_data[i] = *arg_iov++;
/* notice: this means that iov.io_data is passed
: by REFERENCE */
}
ReadDone(ch, time)
Channel *ch;
{
register IoBlock *ip;
ip = ch->ch_read.b_next;
ip->b_proc->p_time = time;
ip->b_proc->p_chid = chidof(ch);
ip->b_proc->p_eventid = 0;
unblock(ip->b_proc, BLOCK_IO);
free(ip->b_data);
ch->ch_read.b_next = ip->b_next;
free(ip);
}
WriteDone(ch, time)
Channel *ch;
{
register IoBlock *ip;
register n;
#ifdef BUFF_CHANS
/* notice: we walk n steps (and not n-1) because the current IO is
* not freed yet. */
for (ip = ch->ch_write.b_next, n = ch->ch_siz;
ip && n > 0;
ip = ip->b_next, n--)
;
if (ip) {
ip->b_proc->p_time = time;
unblock(ip->b_proc, BLOCK_IO);
}
ip = ch->ch_write.b_next;
#else BUFF_CHANS
ip = ch->ch_write.b_next;
ip->b_proc->p_time = time;
unblock(ip->b_proc, BLOCK_IO);
#endif BUFF_CHANS
free(ip->b_data);
ch->ch_write.b_next = ip->b_next;
free(ip);
}
TimeOf(ch)
Channel *ch;
{
/* return -1 if no I/O ready on 'ch', otherwise return the time of the I/O
* operation
*/
register IoBlock *rfirst, *wfirst, *temp;
IoVec *iov;
Expire(ch);
rfirst = ch->ch_read.b_next;
wfirst = ch->ch_write.b_next;
if (IsTime(ch)) {
if (rfirst == NULL)
return -1;
return(rfirst->b_proc->p_time);
}
#ifdef S_SYS
if (IsSpecial(ch)) {
if (rfirst && wfirst)
return (
min(rfirst->b_proc->p_time,wfirst->b_proc->p_time)
);
if (rfirst)
return(rfirst->b_proc->p_time);
if (wfirst)
return(wfirst->b_proc->p_time);
return -1;
}
#endif S_SYS
if (!rfirst :: !wfirst) {
return -1;
}
debug("channel %d is ready for I/O\n", chidof(ch));
return (max(wfirst->b_proc->p_time, rfirst->b_proc->p_time));
}
Expire(ch)
Channel *ch;
{
register IoBlock *rfirst;
register IoBlock *Iob;
rfirst = &ch->ch_read;
while (rfirst->b_next &&
rfirst->b_next->b_next->b_id &&
rfirst->b_next->b_proc->p_eventid != rfirst->b_next->b_id)
{
Iob = rfirst->b_next;
rfirst->b_next = Iob->b_next;
free(Iob->b_data);
free(Iob);
}
}
Size(Ioq)
register IoBlock *Ioq;
{
register i;
for (i = 0; Ioq; Ioq = Ioq->b_next, i++)
;
return i;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'stck.c'
then
echo shar: will not over-write existing file "'stck.c'"
else
cat << \SHAR_EOF > 'stck.c'
static char rcsid[] = "$Header: stck.c,v 3.2 86/11/03 12:35:11 gil Exp $";
/*
* $Log: stck.c,v $
* Revision 3.2 86/11/03 12:35:11 gil
* buffered channels and special channels are wrapped within 'ifdefs' for
* flexible configuration.
*
* Revision 3.1 86/11/01 15:45:04 gil
* A cleaner version, with timeout forced before each synchronization event.
*
* Revision 2.1 86/10/30 18:15:02 gil
* This version was submitted for the project. It is free of all major bugs.
*
* Revision 1.1 86/01/04 14:49:05 gil
* Initial revision
*
*/
#include <stdio.h>
#include "conf.h"
#include "process.h"
caddr_t StackBase;
int StackReserve = 128;
Stack NextStack;
extern kmode;
#ifdef vax
StackExpand(addr, sz, ap)
caddr_t addr, ap;
{
register caddr_t r11, r10, r9;
int i;
Stack s, NewStack();
Kmode_On;
s = proc->p_curstack;
proc->p_curstack = NextStack;
r10 = realtop(proc->p_curstack);
/* printf("stack expand addr: %x sz %d ap %x\n", addr, sz, ap); */
write(1, "#", 1);
asm("movl r10,sp")
/* call to functions will be executed on the new stack from this point */
if(proc->p_curstack.s_size < (i = sz + StackReserve * 2)) {
proc->p_curstack = NewStack(i);
r10 = realtop(proc->p_curstack);
asm("movl r10,sp")
} else
NextStack = NewStack(0);
SetStack(&(proc->p_curstack));
Kmode_Off;
r10 = ap;
r9 = addr;
asm("callg (r10),(r9)")
Kmode_On;
FreeStack(proc->p_curstack);
proc->p_curstack = s;
SetStack(&(proc->p_curstack));
Kmode_Off;
}
#else
StackExpand() {}
#endif
SetStack(s)
register Stack *s;
{
StackBase = s->s_bottom;
}
#ifdef notdef
stacktrace() {
register r12, r11;
r12 = 0;
#ifdef tahoe
asm("moval (sp),r12")
asm("movl fp,r11")
#else vax
asm("movl sp, r11")
asm("movl fp, r10")
#endif
fprintf(stderr, "proc: %d base: %x top: 0x%x sp: 0x%x fp: 0x%x used: %d\n",
proc->p_pid, proc->p_stack.s_bottom,
realtop(proc->p_stack), r12, r11, realtop(proc->p_stack)-r12);
}
#endif
SHAR_EOF
fi # end of overwriting check
if test -f 'test.c'
then
echo shar: will not over-write existing file "'test.c'"
else
cat << \SHAR_EOF > 'test.c'
static char rcsid[] = "$Header: test.c,v 3.1 86/11/01 15:45:06 gil Exp $";
/*
* $Log: test.c,v $
* Revision 3.1 86/11/01 15:45:06 gil
* A cleaner version, with timeout forced before each synchronization event.
*
* Revision 2.1 86/10/30 18:15:05 gil
* This version was submitted for the project. It is free of all major bugs.
*
* Revision 1.1 86/01/04 14:49:07 gil
* Initial revision
*
*/
test(){}
SHAR_EOF
fi # end of overwriting check
if test -f 'vmschan.c'
then
echo shar: will not over-write existing file "'vmschan.c'"
else
cat << \SHAR_EOF > 'vmschan.c'
static char *rcsid = "$Header: vmschan.c,v 3.2 86/11/03 12:35:16 gil Exp $";
#include <stdio.h>
#include "conf.h"
#include "process.h"
#include "chan.h"
#include <sys/ioctl.h>
#include "vmsio.h"
#define IsAtty isatty
extern char *calloc();
#ifdef S_VMS
chat(chid, vmsfd)
{
Channel *ch;
ch = chanof(chid);
ch->ch_flags = CH_VMS;
ch->ch_fd = vmsfd;
}
VmsInit(av)
char **av;
{
static char vmsbuf[256];
while(*av) {
strcat(vmsbuf, *av);
if(*++av == NULL)
break;
strcat(vmsbuf, " ");
}
StdFile[C_Parameters].vms_stat = ARGSTR;
StdFile[C_Parameters].vms_name = vmsbuf;
StdFile[C_Keyboard].vms_stat = NORMAL;
StdFile[C_Keyboard].vms_fp = stdin;
StdFile[C_Screen].vms_stat = NORMAL;
StdFile[C_Screen].vms_fp = stdout;
}
VmsWrite(ch, tm)
Channel *ch;
{
IoBlock *wblk;
IoVec *vv;
register i;
int len;
VmsChan *vc;
vc = VFile(ch->ch_fd);
wblk = ch->ch_write.b_next;
vv = wblk->b_data;
len = wblk->b_ndata;
for(i = 0; i < len; i++, vv++) {
if(vv->io_len != WORDSIZE)
panic("non word messages are not alloud in Vms\n");
Vwrite(vc, *vv->io_data);
}
WriteDone(ch, tm);
}
VmsRead(ch, tm)
Channel *ch;
{
IoBlock *rblk;
IoVec *vv;
int len;
register i;
VmsChan *vc;
vc = VFile(ch->ch_fd);
rblk = ch->ch_read.b_next;
vv = rblk->b_data;
len = rblk->b_ndata;
for(i = 0; i < len; i++, vv++) {
if(vv->io_len != WORDSIZE)
panic("non word messages are not alloud in Vms\n");
Vread(vc, vv->io_data);
}
ReadDone(ch, tm);
}
VmsSelect() {
panic("vms select not implemented yet");
return 0;
}
Vread(vc, c)
VmsChan *vc;
int *c;
{
int cnt;
if(vc->vms_message) {
*c = vc->vms_message;
vc->vms_message = 0;
return;
}
if(vc->vms_stat == ARGSTR) {
if((*c = *(vc->vms_name)) == '\0')
*c = V_EndParameterString;
else
vc->vms_name++;
return;
}
if(vc->vms_fp == NULL)
panic("vms: can't read from closed file\n");
if((vc->vms_fp->_flag & _IOREAD) == 0)
panic("vms: file not open for reading\n");
again:
if(vc->vms_fp->_cnt > 0) {
*c = Getc(vc->vms_fp);
return;
}
if(feof(vc->vms_fp)) {
*c = V_EndFile;
return;
}
if(IsAtty(vc->vms_fp)) {
do
ioctl(fileno(vc->vms_fp), FIONREAD, &cnt);
while(cnt == 0 && vc->vms_fp->_cnt == 0 && Swtch());
goto again;
} else
*c = Getc(vc->vms_fp);
}
Swtch() {
swtch();
return 1;
}
Getc(fp)
FILE *fp;
{
int c;
if((c = getc(fp)) == EOF) {
if(ferror(fp))
c = E_ReadFailed;
else
c = V_EndFile;
}
else if(c == '\n')
c = V_EndRecord;
return c;
}
Flush(vc)
VmsChan *vc;
{
fflush(vc->vms_fp);
if(ferror(vc->vms_fp))
vc->vms_message = E_WriteFailed;
else
vc->vms_message = V_NextRecord;
}
Vwrite(vc, c)
VmsChan *vc;
{
if(c < 0)
goto control;
write:
if(vc->vms_stat == NORMAL) {
if(vc->vms_fp == NULL)
panic("try to write on a closed file\n");
putc(c, vc->vms_fp);
if(c == '\n')
Flush(vc);
} else
if(vc->vms_stat == FILENAME)
AddC(vc, c);
return;
control:
switch (c) {
case V_EndRecord:
c = '\n';
goto write;
case V_NextRecord:
break;
case V_EndBuffer:
if(vc->vms_fp == NULL)
panic("flushing a closed file\n");
Flush(vc);
break;
case V_OpenForRead:
vc->vms_message = V_OpenForRead;
vc->vms_stat = FILENAME;
vc->vms_name = calloc(256, 1); /* XXX */
break;
case V_OpenForWrite:
vc->vms_message = V_OpenForWrite;
vc->vms_stat = FILENAME;
vc->vms_name = calloc(256, 1); /* XXX */
break;
case V_EndName:
OpenFile(vc);
break;
case V_CloseFile:
CloseFile(vc);
break;
case V_EndFile:
Flush(vc);
break;
default:
panic("bad request\n");
}
}
OpenFile(vc)
VmsChan *vc;
{
char *ms;
if(vc->vms_message == V_OpenForRead)
ms = "r";
else
ms = "w";
vc->vms_fp = fopen(vc->vms_name+1, ms);
if(vc->vms_fp == NULL)
vc->vms_message = (vc->vms_message == V_OpenForRead) ?
E_InputFileNotOpened :
E_OutputFileNotCreated;
else
vc->vms_message = V_OpenedOK;
vc->vms_stat = NORMAL;
free(vc->vms_name);
}
AddC(vc, c)
VmsChan *vc;
{
vc->vms_name[++(vc->vms_name[0])] = c;
}
CloseFile(vc)
VmsChan *vc;
{
if(vc->vms_fp == NULL)
panic("trying to close a closed file\n");
fclose(vc->vms_fp);
vc->vms_message = V_ClosedOK;
vc->vms_fp = NULL;
}
#endif S_VMS
SHAR_EOF
fi # end of overwriting check
if test -f 'chan.c'
then
echo shar: will not over-write existing file "'chan.c'"
else
cat << \SHAR_EOF > 'chan.c'
static char rcsid[] = "$Header: chan.c,v 3.4 86/11/03 12:34:21 gil Exp $";
/*
: $Header: chan.c,v 3.4 86/11/03 12:34:21 gil Exp $
*/
/* $Log: chan.c,v $
* Revision 3.4 86/11/03 12:34:21 gil
* buffered channels and special channels are wrapped within 'ifdefs' for
* flexible configuration.
*
* Revision 3.3 86/11/03 11:08:08 gil
* this version supports buffered channel.
*
* Revision 3.2 86/11/02 09:37:03 gil
* fixed the race (Kmode_On should be BEFORE resched).
*
* Revision 3.1 86/11/01 15:48:04 gil
* A cleaner version, with timeout forced before each synchronization event.
*
* Revision 2.1 86/10/30 18:14:49 gil
* This version was submitted for the project. It is free of all major bugs.
*
* Revision 1.4 86/08/04 17:24:35 gil
* 1. fixed few bugs
* 2. change format of tracing messages
*
* Revision 1.3 86/05/29 10:28:49 gil
* this version fits the new ready-requests-queue mechanism.
*
*/
#include <stdio.h>
#include "conf.h"
#include "process.h"
#include "chan.h"
Channel chans[MAX_CHANS];
Channel *free_chans;
extern char *calloc();
int Eventid = 1;
int time_ch; /* keep the special time channel */
InitChans() {
register i, j;
for(i = 0, j = MAX_CHANS - 1; i < j; i++)
chans[i].ch_nxt = &chans[i+1];
chans[j].ch_nxt = NULL;
free_chans = chans;
}
chopen(siz)
{
register Channel *ch;
Kmode_On;
if (free_chans == NULL) {
panic("no more channels\n");
/*NOTREACHED*/
}
ch = free_chans;
free_chans = free_chans->ch_nxt;
Kmode_Off;
TRACE(TRACE_IO, ("opened %d(%d)", ch-chans, siz));
ch->ch_siz = siz;
ch->ch_read.b_next = NULL;
ch->ch_write.b_next = NULL;
return (ch - chans);
}
chclose(chid) {
register Channel *ch;
Kmode_On;
if (chid < 0 :: chid >= MAX_CHANS)
panic("bad channel\n");
ch = &chans[chid];
ch->ch_nxt = free_chans;
free_chans = ch;
ch->ch_read.b_next = 0;
ch->ch_write.b_next = 0;
TRACE(TRACE_IO, ("closed %d", chid));
Kmode_Off;
}
chread(chid, flags, len, iov)
IoVec iov;
{
register Channel *ch;
register tm;
ch = chanof(chid);
timesync(proc);
TRACE(TRACE_IO, ("read on %d", chid));
if (IsTime(ch) && (flags & BD_FAFTER)) {
proc->p_time =
max(proc->p_time, *((int *)(iov.io_data)));
timewrite(proc);
return;
}
Kmode_On;
resched(0);
EnterRequest(&(ch->ch_read), flags, len, &iov, 0);
if ((tm = TimeOf(ch)) >= 0)
IO(ch, tm);
else
block(proc, BLOCK_IO);
Kmode_Off;
}
chwrite(chid, flags, len, iov)
IoVec iov;
{
register Channel *ch;
register tm;
ch = chanof(chid);
timesync(proc);
TRACE(TRACE_IO, ("write on %d", chid));
Kmode_On;
resched(0);
EnterRequest(&(ch->ch_write), flags, len, &iov, 0);
if ((tm = TimeOf(ch)) >= 0)
IO(ch, tm);
#ifdef BUFF_CHANS
else if (!ch->ch_siz :: Size(ch->ch_write.b_next) > ch->ch_siz)
#else
else
#endif
block(proc, BLOCK_IO);
Kmode_Off;
}
char *
chselect(nargs, arg1)
{
struct IoReq {
int chid;
int nret; /* saved data buf length */
int flags;
int len;
IoVec iov;
/* Saved data [nret*4] */
} *ap = (struct IoReq *)&arg1, *cp = ap;
Channel *ch;
/*
: This requires explanation:
: We push quintets of < chid, nret, flags, len, iov > as accepted
: by 'chread'/'chwrite'. the problem is the 'iov' is actually a vector
: of struct IoVec, and its length is given by 'len', and at the end of
: each quintet is a data-buffer of length 'nret' * intsize.
: So, when we advance to next quintet, the increment is of dynamic size,
: which is:
: sizeof (chid)
: + sizeof (flags)
: + sizeof (len)
: + sizeof (nret)
: + len * sizeof (iov)
: + nret * sizeof (int)
*/
register i, n;
int ret;
char *p;
char b[5];
static char buf[512];
Channel *chose = NULL;
Kmode_On;
Eventid++;
sprintf(buf, "select on:");
proc->p_eventid = Eventid;
timesync(proc);
resched(1); /* let all the write-requests to get ready */
resched(1); /* let all the write-requests be acutally delivered */
for(n = 1, i = nargs; i > 0; i--) {
sprintf(b, " %d", cp->chid);
strcat(buf, b);
ch = chanof(cp->chid);
EnterRequest(&(ch->ch_read), cp->flags, cp->len,
&(cp->iov), Eventid);
if (TimeOf(ch) >= 0) {
if ((random() & MASKR) < (R / (float)n))
/* first one alwaysgets chosen */
chose = ch;
n++;
}
cp = (struct IoReq *) ((char *)cp +
sizeof(IoVec) * (cp->len-1) +
cp->nret * sizeof(int));
cp++;
}
TRACE(TRACE_IO, (buf));
if (chose != NULL)
IO(chose, TimeOf(chose));
else
block(proc, BLOCK_IO);
for(cp = ap, i = nargs; i > 0; i--) {
if(cp->chid == proc->p_chid) {
p = (char *)(cp+1) + (cp->len - 1)* sizeof(IoVec);
debug("chselect: 1st reg is %d\treg mask %x\n",
((int *)p)[1], *((int *)p));
debug("chselect: len = %d\n", cp->len);
TRACE(TRACE_IO,
("channel %d selected", cp->chid));
Kmode_Off;
return p;
}
cp = (struct IoReq *) ((char *)cp +
sizeof(IoVec) * (cp->len-1) +
cp->nret * sizeof(int));
cp++;
}
panic("select channel disappeared");
Kmode_Off;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
# configurable parameters.
################################################################################
DESTDIR=/m/usr/gil
CC=cc
AS=as
CFLAGS=-Ih -g
################################################################################
LIB=lsim.a
OBJS= chan.o\
chq.o\
ext.o\
machdep.o\
proto.o\
sched.o\
stck.o\
sysio.o\
test.o\
vmschan.o\
${EMPTY}
$(LIB): $(OBJS)
ar cr $(LIB) $(OBJS)
ranlib $(LIB)
install: $(LIB)
mv $(LIB) $(DESTDIR)/lib/lsim.a
ranlib $(DESTDIR)/lib/lsim.a
# dependencies on header files
################################################################################
chan.c: h/conf.h
chan.c: h/process.h
chan.c: h/chan.h
chq.c: h/conf.h
chq.c: h/process.h
chq.c: h/chan.h
ext.c: h/trace.h
sched.c: h/conf.h
sched.c: h/process.h
stck.c: h/conf.h
stck.c: h/process.h
sysio.c: h/conf.h
sysio.c: h/process.h
sysio.c: h/chan.h
vmschan.c: h/conf.h
vmschan.c: h/process.h
vmschan.c: h/chan.h
vmschan.c: h/vmsio.h
SHAR_EOF
fi # end of overwriting check
if test -f 'machdep.s.vax'
then
echo shar: will not over-write existing file "'machdep.s.vax'"
else
cat << \SHAR_EOF > 'machdep.s.vax'
# set/long jmp, no documatation since the source got lost, this is a
# disassembly.
.globl _SetJmp
_SetJmp: .word 0x0
movl 4(ap),r1
movq r2,(r1)+
movq r4,(r1)+
movq r6,(r1)+
movq r8,(r1)+
movq r10,(r1)+
movq 8(fp),(r1)+
moval 4(ap),(r1)+
movl 16(fp),(r1)+
movl $0,r0
ret
.globl _LongJmp
_LongJmp: .word 0x0
movl 4(ap),r1
movq (r1)+,r2
movq (r1)+,r4
movq (r1)+,r6
movq (r1)+,r8
movq (r1)+,r10
movq (r1)+,ap
movl (r1)+,sp
movl $1,r0
jmp *(r1)
SHAR_EOF
fi # end of overwriting check
if test -f 'sched.c'
then
echo shar: will not over-write existing file "'sched.c'"
else
cat << \SHAR_EOF > 'sched.c'
static char rcsid[] = "$Header: sched.c,v 3.3 87/02/17 10:55:41 gil Exp $";
/*
* $Log: sched.c,v $
* Revision 3.3 87/02/17 10:55:41 gil
* Eventid removed.
*
* Revision 3.2 86/11/03 12:35:07 gil
* buffered channels and special channels are wrapped within 'ifdefs' for
* flexible configuration.
*
* Revision 3.1 86/11/01 15:42:58 gil
* *** empty log message ***
*
* Revision 2.1 86/10/30 18:14:59 gil
* This version was submitted for the project. It is free of all major bugs.
*
* Revision 1.6 86/07/07 17:08:34 gil
* Cleaner version.
* Removed cpu clock, sched and unused variables.
*
* Revision 1.5 86/07/07 16:47:12 gil
* Working version.
*
* Revision 1.3 86/03/24 14:55:52 gil
* added time synchronization for waiting processes.
*
* Revision 1.2 86/03/17 13:50:58 gil
* *** empty log message ***
*
*/
#include <stdio.h>
#include <sys/time.h>
#include "conf.h"
#include "process.h"
#define max(a, b) ((a) > (b) ? (a) : (b))
Process *proc;
/* dummy-firsts for: */
Process wdummy, /* wait-queue */
rdummy, /* run-queue */
fdummy; /* free-queue */
int kmode;
extern char *malloc();
#ifdef vax
#define savefp() asm(" movl 12(fp), r11")
#define saveap() asm(" movl 8(fp), r11")
#else tahoe
#define savefp() asm(" movl (fp), r12")
#endif
Process *
nextrun()
{
Process *run;
run = runq->p_nxt;
if (run == NULL)
Deadlock();
return run;
}
swtch() {
register caddr_t fp; /* must be r11(vax) r12(tahoe) */
register Process *p;
int savedkmode = 0;
p = nextrun();
savefp();
if(proc && !StackMask(proc))
panic("Process Stack Underflow");
if(p == proc) /* no context switching is done - return */
return;
if(proc != NULL)
if(save(proc)) { /* save status */
debug("start %d with kmode %d\n",
proc-proctable, savedkmode);
return;
}
if(!StackMask(p))
panic("Process %s Stack Damaged", Pinfo(p));
TRACE(TRACE_CSW, ("switching to %s", Pinfo(p)));
resume(p); /* transfer control to p - return on previous
: line... */
}
save(p)
Process *p;
{
p->p_kmode = kmode;
return SetJmp(&(p->p_save));
}
resume(p)
Process *p;
{
debug("resuming %d pc %x\n", (p - proctable), p->p_save.st_pc);
proc = p;
SetStack(&(proc->p_curstack));
kmode = p->p_kmode;
sigsetmask(0);
LongJmp(&(p->p_save));
/*NOTREACHED*/
}
/* tick - interupt routine, called on each clock tick. */
tick() {
if (kmode) {
sigsetmask(0);
return;
}
Kmode_On;
resched(0);
debug("kmode: %d\n", kmode);
Kmode_Off;
return;
}
resched(pri)
{
if (proc != NULL) {
timesync(proc);
FreeMe(proc);
if (pri)
PriEnterMe(proc, runq);
else
EnterMe(proc, runq);
}
swtch();
}
int DefaultStackSize = STACK_SIZE;
Stack
NewStack(sz)
{
Stack s;
if(sz == 0)
sz = DefaultStackSize;
s.s_bottom = malloc(sz);
if(s.s_bottom == NULL)
panic("alloc stack failed\n");
s.s_bottom[0] = SMASK;
s.s_size = sz;
return s;
}
FreeStack(s)
Stack s;
{
free(s.s_bottom);
}
Process *
freeslot() {
register Process *p;
p = freeq->p_nxt;
if(p == NULL)
panic("no more process\n");
freeq->p_nxt = p->p_nxt;
p->p_nxt = NULL;
p->p_prv = NULL;
return p;
}
newproc(addr)
caddr_t addr;
{
register caddr_t save; /* Must be in r11 (r12 on tahoe) */
/**** Don't use any other register for local storage ****/
Process *p, *q;
Kmode_On;
p = proc;
p->p_nsons++;
q = freeslot();
q->p_pid = genpid();
q->p_ppid = p->p_pid;
q->p_parent = p;
q->p_nzomb = q->p_nsons = q->p_sontime = 0;
timesync(p);
q->p_time = p->p_time; /* start with father's time */
q->p_flags = 0;
q->p_stack = NewStack(0);
q->p_curstack = q->p_stack;
SetJmp(&(q->p_save));
q->p_save.st_dp = dispof(q->p_stack);
#ifdef vax
saveap();
q->p_save.st_ap = save;
#endif
savefp();
q->p_save.st_fp = save;
q->p_save.st_sp = topof(q->p_stack);
q->p_save.st_pc = addr;
q->p_kmode = 0;
/* Initialize the display */
bcopy(bdispof(p->p_stack), bdispof(q->p_stack), DISPSIZE);
timewrite(q);
TRACE(TRACE_FORK, ("create %d at 0x%x", q->p_pid, addr));
setrun(q);
Kmode_Off;
return;
}
endproc() {
Kmode_On;
timesync(proc);
TRACE(TRACE_FORK, ("ended"));
debug("endproc %d\n", proc - proctable);
FreeMe(proc);
if(proc->p_parent) {
proc->p_parent->p_nsons--;
WakePapa(proc->p_parent);
/* Dalia was slightly drunk when she wrote this.
: please don't change */
}
if (proc->p_nsons > 0 :: proc->p_nzomb > 0) {
proc->p_flags := PF_ZOMB;
if(proc->p_parent)
proc->p_parent->p_nzomb++;
while(proc->p_nsons > 0 :: proc->p_nzomb > 0)
block(proc, BLOCK_CHILD);
if(proc->p_parent)
proc->p_parent->p_nzomb--;
WakePapa(proc->p_parent);
}
EnterMe(proc, freeq);
FreeStack(proc->p_stack);
proc = NULL;
swtch();
/*NOTREACHED*/
}
setrun(p)
Process *p;
{
debug("setrun: %d\n", p-proctable);
p->p_stat = RUNNING;
EnterMe(p, runq);
}
WakePapa(papa)
Process *papa;
{
if(papa) {
papa->p_sontime = max(papa->p_sontime, proc->p_time);
if(papa->p_nsons == 0)
unblock(papa, BLOCK_CHILD);
}
}
waitall() {
Kmode_On;
timesync(proc);
while (proc->p_nsons > 0)
block(proc, BLOCK_CHILD);
proc->p_time = proc->p_sontime;
proc->p_sontime = 0;
timewrite(proc);
Kmode_Off;
}
genpid() {
static pid = 1;
return pid++;
}
extern Stack NextStack;
initproc() {
register j, i;
Kmode_On;
NextStack = NewStack(0);
for(i = 1, j = nproc - 1; i < j; i++) {
proctable[i].p_nxt = &proctable[i+1];
proctable[i+1].p_prv = &proctable[i];
}
proctable[j].p_nxt = NULL;
freeq = &fdummy;
fdummy.p_nxt = &proctable[1];
proctable[1].p_prv = freeq;
wdummy.p_nxt = wdummy.p_prv = NULL;
waitq = &wdummy;
proc = &proctable[0];
runq = &rdummy;
rdummy.p_nxt = proc;
rdummy.p_prv = NULL;
proc->p_prv = runq;
Kmode_Off;
}
block(p, block_stat)
Process *p;
enum pstat block_stat;
{
TRACE(TRACE_BLOCK, ("blocked, on %s", BlockStat(block_stat)));
debug("block %d\n", p - proctable);
p->p_stat = block_stat;
FreeMe(p);
EnterMe(p, waitq);
if (proc == p)
swtch();
}
unblock(p, block_stat)
Process *p;
enum pstat block_stat;
{
debug("unblock %d\n", p - proctable);
TRACE(TRACE_BLOCK,
("unblock %s, on %s", Pinfo(p), BlockStat(block_stat)));
if (p->p_stat == block_stat) {
timewrite(p);
FreeMe(p);
setrun(p);
}
}
EnterMe(pp, queue)
Process *pp, *queue;
{
register n;
register Process *q, *chose;
for (q = queue;
q->p_nxt && q->p_nxt->p_time < pp->p_time;
q = q->p_nxt)
;
for (chose = q, n = 2;
q->p_nxt && q->p_nxt->p_time == pp->p_time;
q = q->p_nxt, n++)
if ((random() & MASKR) < (R / (float)n))
chose = q->p_nxt;
pp->p_nxt = chose->p_nxt;
pp->p_prv = chose;
if (chose->p_nxt)
chose->p_nxt->p_prv = pp;
chose->p_nxt = pp;
}
PriEnterMe(pp, queue)
Process *pp, *queue;
{
register Process *q;
for (q = queue;
q->p_nxt && q->p_nxt->p_time <= pp->p_time;
q = q->p_nxt)
;
pp->p_nxt = q->p_nxt;
pp->p_prv = q;
if (q->p_nxt)
q->p_nxt->p_prv = pp;
q->p_nxt = pp;
}
FreeMe(p)
Process *p;
{
register Process *q;
q = p->p_nxt;
if(p->p_prv != NULL)
p->p_prv->p_nxt = q;
if(q != NULL)
q->p_prv = p->p_prv;
}
Deadlock() {
if (waitq->p_nxt != NULL)
panic("deadlock\n");
printf("process terminated successfully\n");
exit(0);
}
timesync(p)
Process *p;
{
p->p_time = *(int *)timeof(p->p_stack);
debug("[%d] time %d\n", proc-proctable, p->p_time);
}
timewrite(p)
Process *p;
{
*(int *) timeof(p->p_stack) = p->p_time;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'proto.c'
then
echo shar: will not over-write existing file "'proto.c'"
else
cat << \SHAR_EOF > 'proto.c'
static char rcsid[] = "$Header: proto.c,v 3.2 86/11/03 12:35:04 gil Exp $";
/*
* $Log: proto.c,v $
* Revision 3.2 86/11/03 12:35:04 gil
* buffered channels and special channels are wrapped within 'ifdefs' for
* flexible configuration.
*
* Revision 3.1 86/11/01 15:48:08 gil
* A cleaner version, with timeout forced before each synchronization event.
*
* Revision 2.1 86/10/30 18:14:57 gil
* This version was submitted for the project. It is free of all major bugs.
*
* Revision 1.1 86/01/04 14:49:02 gil
* Initial revision
*
*/
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include "conf.h"
#include "process.h"
extern tick();
#define ALOT (512*1024)
static char display[DISPSIZE+COUNTSIZE];
extern dflag;
int qflag;
extern DefaultStackSize, StackReserve;
char *progname;
int CommandsTime;
main(ac, av)
char **av;
{
register char *r11, i = 25;
int oc_main();
progname = av[0];
tracef = stderr;
setlinebuf(stderr);
while(**++av == '-')
switch(*++*av) {
case 'd':
dflag++;
break;
case 's':
{
int s = atoi(++*av);
if(s < DISPSIZE+64) {
fprintf(stderr, "%d: Stack too small\n", s);
break;
}
debug("StackSize: %d\n", s);
DefaultStackSize = s;
break;
}
case 'r':
{
int s = atoi(++*av);
if(s < 0) {
fprintf(stderr, "Cannot UnReserve stack\n");
break;
}
debug("ReserveStack: %d\n", s);
StackReserve = s;
break;
}
case 'i':
i = atoi(++*av);
if(i < 1) {
fprintf(stderr, "%d: Bad interval\n",
i);
i = 25;
}
debug("Will interupt %d times/sec\n", i);
break;
case 't':
if(*++*av == '\0')
tracer := TRACE_ALL;
else
tracer := tflag(*av);
break;
case 'q':
qflag++;
break;
case 'f':
if(*++*av == '\0')
tracef = stdout;
else {
if((tracef = fopen(*av, "w")) == NULL) {
fprintf(stderr,
"Cannot open trace file ");
fflush(stderr);
perror(*av);
exit(1);
}
}
break;
default:
fprintf (stderr, "%c: Unknown option\n", **av);
break;
}
srandom((int)time(0));
initproc();
InitChans();
#ifdef S_VMS
VmsInit(av);
#endif S_VMS
signal(SIGVTALRM, tick);
inton(i);
r11 = &display[DISPSIZE+COUNTSIZE];
proc->p_stack.s_bottom = r11 - ALOT;
proc->p_stack.s_size = ALOT;
newproc(oc_main);
test();
waitall();
if(!qflag)
fprintf(stderr,
"Executed %d instructions in %d time\n",
CommandsTime, proctable[0].p_time);
exit(0);
}
intoff() {
struct itimerval it;
it.it_interval.tv_sec = it.it_value.tv_usec = 0;
it.it_value = it.it_interval;
setitimer(ITIMER_VIRTUAL, &it, 0);
}
int Ival; /* IPS */
inton(t) {
struct itimerval it;
Ival = t;
it.it_interval.tv_usec = 1000000/t;
it.it_interval.tv_sec = 0;
it.it_value = it.it_interval;
setitimer(ITIMER_VIRTUAL, &it, 0);
}
panic(s, a1, a2, a3, a4) {
fprintf(stderr, "Panic: %s: ", Pinfo(proc));
fprintf(stderr, s, a1, a2, a3, a4);
putc('\n', stderr);
exit(1);
}
tflag(s)
char *s;
{
int f = 0;
while(*s) {
switch (*s) {
case 'c':
f := TRACE_CSW;
break;
case 'f':
case 's':
f := TRACE_FORK;
break;
case 'b':
f := TRACE_BLOCK;
break;
case 'a':
f := TRACE_ALLIO;
break;
case 'i':
f := TRACE_IO;
break;
default:
fprintf(stderr, "%c: unknown trace flag\n",
*s);
break;
}
s++;
}
return f;
}
int tracer;
char *tstr = "\1CSW\0\2FORK\0\4BLOCK\0\010TIME\0\020IO\0\040MOREIO\0\100CPUT";
pflg(flg)
{
fprintf(tracef, "%s", Pinfo(proc));
nflg(flg);
}
sflg(flg)
{
fprintf(tracef, "[ Sys ]");
nflg(flg);
}
char *
Pinfo(p)
Process *p;
{
static char buf[3][128];
static use;
register char *s;
s = buf[use++%3];
if(p)
sprintf(s, "[%-3d,%2d]", p->p_pid, p->p_time);
else
sprintf(s, "[ Nop ]");
}
char *
BlockStat(b)
enum pstat b;
{
switch (b) {
case BLOCK_CHILD:
return "child event";
case BLOCK_IO:
return "I/O event";
case RUNNING:
return "Running???!!!";
default:
return "Unknown Status";
}
}
nflg(flg)
{
register char *s;
register once = 0, c;
putc('<', tracef);
for(s = tstr; *s; s++) {
c = *s;
if(c & flg) {
if(once)
putc(',', tracef);
once = 1;
while(*++s)
putc(*s, tracef);
} else
while(*++s)
;
}
putc('>', tracef);
putc(' ', tracef);
}
/*VARARGS*/
ptrace(fmt, a1, a2, a3, a4, a5, a6)
char *fmt;
{
fprintf(tracef, fmt, a1, a2, a3, a4, a5, a6);
putc('\n', tracef);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'sched.s'
then
echo shar: will not over-write existing file "'sched.s'"
else
cat << \SHAR_EOF > 'sched.s'
.data
.data
_rcsid:.long 0x61654824
.long 0x3a726564
.long 0x68637320
.long 0x632e6465
.long 0x3320762c
.long 0x3820322e
.long 0x31312f36
.long 0x2033302f
.long 0x333a3231
.long 0x37303a35
.long 0x6c696720
.long 0x70784520
.long 0x2420
.comm _runq,4
.comm _waitq,4
.comm _freeq,4
.comm _proctable,32768
.comm _tracef,4
.comm _proc,4
.comm _wdummy,128
.comm _rdummy,128
.comm _fdummy,128
.comm _kmode,4
.text
LL0:.align 1
.globl _nextrun
.set L41,0x0
.data
.text
_nextrun:.word L41
subl2 $4,sp
movl _runq,r0
movl 44(r0),-4(fp)
jneq L45
calls $0,_Deadlock
L45:movl -4(fp),r0
ret
.align 1
.globl _swtch
.data 1
L57:.ascii "start %d with kmode %d\12\0"
.text
.data 1
L61:.ascii "switching to %s\0"
.text
.set L48,0x800
.data
.text
_swtch:.word L48
subl2 $4,sp
clrl -4(fp)
calls $0,_nextrun
movl r0,r11
cmpl r11,_proc
jneq L52
ret
L52:tstl _proc
jeql L53
pushl _proc
calls $1,_save
tstl r0
jeql L53
pushl -4(fp)
subl3 $_proctable,_proc,r0
divl3 $128,r0,-(sp)
pushal L57
calls $3,_debug
ret
L53:jlbc _tracer,L58
pushl $1
calls $1,_pflg
pushl r11
calls $1,_Pinfo
pushl r0
pushal L61
calls $2,_ptrace
L58:pushl r11
calls $1,_resume
ret
.align 1
.globl _save
.set L63,0x0
.data
.text
_save:.word L63
movl 4(ap),r0
movl _kmode,108(r0)
addl3 $52,4(ap),-(sp)
calls $1,_SetJmp
ret
.align 1
.globl _resume
.data 1
L72:.ascii "resuming %d pc %x\12\0"
.text
.set L68,0x0
.data
.text
_resume:.word L68
movl 4(ap),r0
pushl 104(r0)
subl3 $_proctable,r0,r0
divl3 $128,r0,-(sp)
pushal L72
calls $3,_debug
movl 4(ap),_proc
addl3 $120,_proc,-(sp)
calls $1,_SetStack
movl 4(ap),r0
movl 108(r0),_kmode
pushl $0
calls $1,_sigsetmask
addl3 $52,4(ap),-(sp)
calls $1,_LongJmp
ret
.align 1
.globl _tick
.data 1
L83:.ascii "kmode\72 %d\12\0"
.text
.set L77,0x0
.data
.text
_tick:.word L77
tstl _kmode
jeql L81
pushl $0
calls $1,_sigsetmask
ret
L81:incl _kmode
pushl $0
calls $1,_resched
pushl _kmode
pushal L83
calls $2,_debug
decl _kmode
ret
.align 1
.globl _resched
.set L84,0x0
.data
.align 2
.globl _DefaultStackSize
_DefaultStackSize:.long 8192
.text
_resched:.word L84
tstl _proc
jeql L88
pushl _proc
calls $1,_timesync
pushl _proc
calls $1,_FreeMe
tstl 4(ap)
jeql L91
pushl _runq
pushl _proc
calls $2,_PriEnterMe
jbr L88
L91:pushl _runq
pushl _proc
calls $2,_EnterMe
L88:calls $0,_swtch
ret
.align 1
.globl _NewStack
.data 1
L104:.ascii "alloc stack failed\12\0"
.text
.lcomm L105,8
.set L97,0x0
.data
.text
_NewStack:.word L97
subl2 $8,sp
tstl 4(ap)
jneq L101
movl _DefaultStackSize,4(ap)
L101:pushl 4(ap)
calls $1,_malloc
movl r0,-4(fp)
tstl r0
jneq L102
pushal L104
calls $1,_panic
L102:movl 4(ap),-8(fp)
moval -8(fp),r0
movab L105,r1
movq (r0),(r1)
movab L105,r0
ret
.align 1
.globl _FreeStack
.set L107,0x0
.data
.text
_FreeStack:.word L107
pushl 8(ap)
calls $1,_free
ret
.align 1
.globl _freeslot
.data 1
L118:.ascii "no more process\12\0"
.text
.set L113,0x800
.data
.text
_freeslot:.word L113
movl _freeq,r0
movl 44(r0),r11
jneq L117
pushal L118
calls $1,_panic
L117:movl _freeq,r0
movl 44(r11),44(r0)
clrl 44(r11)
clrl 48(r11)
movl r11,r0
ret
.align 1
.globl _newproc
.data 1
L128:.ascii "create %d at 0x%x\0"
.text
.set L120,0x800
.data
.text
_newproc:.word L120
subl2 $8,sp
incl _kmode
movl _proc,-4(fp)
movl -4(fp),r0
incl 12(r0)
calls $0,_freeslot
movl r0,-8(fp)
calls $0,_genpid
movl r0,*-8(fp)
movl -8(fp),r0
movl *-4(fp),4(r0)
movl -8(fp),r0
movl -4(fp),8(r0)
movl -8(fp),r0
clrl 20(r0)
movl -8(fp),r1
movl 20(r0),12(r1)
movl -8(fp),r0
movl 12(r1),16(r0)
pushl -4(fp)
calls $1,_timesync
movl -4(fp),r0
movl -8(fp),r1
movl 24(r0),24(r1)
movl -8(fp),r0
clrl 28(r0)
pushl $0
calls $1,_NewStack
addl3 $112,-8(fp),r1
movq (r0),(r1)
addl3 $112,-8(fp),r0
addl3 $120,-8(fp),r1
movq (r0),(r1)
addl3 $52,-8(fp),-(sp)
calls $1,_SetJmp
movl -8(fp),r0
movl r0,r1
addl3 112(r1),116(r0),r0
subl2 $4,r0
movl r0,88(r1)
movl 8(fp), r11
movl -8(fp),r0
movl r11,92(r0)
movl 12(fp), r11
movl -8(fp),r0
movl r11,96(r0)
movl -8(fp),r0
movl r0,r1
addl3 112(r1),116(r0),r0
subl2 $68,r0
movl r0,100(r1)
movl -8(fp),r0
movl 4(ap),104(r0)
movl -8(fp),r0
clrl 108(r0)
pushl $64
movl -8(fp),r0
movl r0,r1
addl3 112(r1),116(r0),r0
subl3 $68,r0,-(sp)
movl -4(fp),r0
movl r0,r1
addl3 112(r1),116(r0),r0
subl3 $68,r0,-(sp)
calls $3,_bcopy
pushl -8(fp)
calls $1,_timewrite
jbc $1,_tracer,L127
pushl $2
calls $1,_pflg
pushl 4(ap)
pushl *-8(fp)
pushal L128
calls $3,_ptrace
L127:pushl -8(fp)
calls $1,_setrun
decl _kmode
ret
.align 1
.globl _endproc
.data 1
L136:.ascii "ended\0"
.text
.data 1
L137:.ascii "endproc %d\12\0"
.text
.set L131,0x0
.data
.text
_endproc:.word L131
incl _kmode
pushl _proc
calls $1,_timesync
jbc $1,_tracer,L135
pushl $2
calls $1,_pflg
pushal L136
calls $1,_ptrace
L135:subl3 $_proctable,_proc,r0
divl3 $128,r0,-(sp)
pushal L137
calls $2,_debug
pushl _proc
calls $1,_FreeMe
movl _proc,r0
tstl 8(r0)
jeql L138
movl 8(r0),r0
decl 12(r0)
movl _proc,r0
pushl 8(r0)
calls $1,_WakePapa
L138:movl _proc,r0
tstl 12(r0)
jgtr L9999
tstl 16(r0)
jleq L140
L9999:movl _proc,r0
bisl2 $1,28(r0)
movl _proc,r0
tstl 8(r0)
jeql L142
movl 8(r0),r0
incl 16(r0)
jbr L142
L9998:pushl $0
pushl _proc
calls $2,_block
L142:movl _proc,r0
tstl 12(r0)
jgtr L9998
tstl 16(r0)
jgtr L9998
tstl 8(r0)
jeql L145
movl 8(r0),r0
decl 16(r0)
L145:movl _proc,r0
pushl 8(r0)
calls $1,_WakePapa
L140:pushl _freeq
pushl _proc
calls $2,_EnterMe
movl _proc,r0
subl2 $8,sp
movq 112(r0),(sp)
calls $2,_FreeStack
clrl _proc
calls $0,_swtch
ret
.align 1
.globl _setrun
.data 1
L150:.ascii "setrun\72 %d\12\0"
.text
.set L146,0x0
.data
.text
_setrun:.word L146
subl3 $_proctable,4(ap),r0
divl3 $128,r0,-(sp)
pushal L150
calls $2,_debug
movl 4(ap),r0
movl $2,40(r0)
pushl _runq
pushl 4(ap)
calls $2,_EnterMe
ret
.align 1
.globl _WakePapa
.set L151,0x0
.data
.text
_WakePapa:.word L151
tstl 4(ap)
jeql L155
movl 4(ap),r0
movl _proc,r1
cmpl 20(r0),24(r1)
jleq L9997
movl 20(r0),r0
jbr L9996
L9997:movl _proc,r0
movl 24(r0),r0
L9996:movl 4(ap),r1
movl r0,20(r1)
movl 4(ap),r0
tstl 12(r0)
jneq L155
pushl $0
pushl r0
calls $2,_unblock
L155:ret
.align 1
.globl _waitall
.set L159,0x0
.data
.text
_waitall:.word L159
incl _kmode
pushl _proc
calls $1,_timesync
jbr L163
L2000002:pushl $0
pushl _proc
calls $2,_block
L163:movl _proc,r0
tstl 12(r0)
jgtr L2000002
movl r0,r1
movl 20(r0),24(r1)
movl _proc,r0
clrl 20(r0)
pushl _proc
calls $1,_timewrite
decl _kmode
ret
.align 1
.globl _genpid
.data
.align 2
L169:.long 1
.text
.set L165,0x0
.data
.text
_genpid:.word L165
movl L169,r0
incl L169
ret
.align 1
.globl _initproc
.set L172,0xc00
.data
.text
_initproc:.word L172
incl _kmode
pushl $0
calls $1,_NewStack
movq (r0),_NextStack
movl $1,r10
movzbl $255,r11
jbr L178
L2000004:addl3 $1,r10,r0
ashl $7,r0,r0
addl2 $_proctable,r0
ashl $7,r10,r1
movl r0,_proctable+44(r1)
ashl $7,r10,r0
addl2 $_proctable,r0
addl3 $1,r10,r1
ashl $7,r1,r1
movl r0,_proctable+48(r1)
incl r10
L178:cmpl r10,r11
jlss L2000004
ashl $7,r11,r0
clrl _proctable+44(r0)
moval _fdummy,_freeq
moval _proctable+128,_fdummy+44
movl _freeq,_proctable+176
clrl _wdummy+48
movl _wdummy+48,_wdummy+44
moval _wdummy,_waitq
moval _proctable,_proc
moval _rdummy,_runq
movl _proc,_rdummy+44
clrl _rdummy+48
movl _proc,r0
movl _runq,48(r0)
decl _kmode
ret
.align 1
.globl _block
.data 1
L184:.ascii "blocked, on %s\0"
.text
.data 1
L185:.ascii "block %d\12\0"
.text
.set L179,0x0
.data
.text
_block:.word L179
jbc $2,_tracer,L183
pushl $4
calls $1,_pflg
pushl 8(ap)
calls $1,_BlockStat
pushl r0
pushal L184
calls $2,_ptrace
L183:subl3 $_proctable,4(ap),r0
divl3 $128,r0,-(sp)
pushal L185
calls $2,_debug
movl 4(ap),r0
movl 8(ap),40(r0)
pushl 4(ap)
calls $1,_FreeMe
pushl _waitq
pushl 4(ap)
calls $2,_EnterMe
cmpl _proc,4(ap)
jneq L186
calls $0,_swtch
L186:ret
.align 1
.globl _unblock
.data 1
L191:.ascii "unblock %d\12\0"
.text
.data 1
L193:.ascii "unblock %s, on %s\0"
.text
.set L187,0x0
.data
.text
_unblock:.word L187
subl3 $_proctable,4(ap),r0
divl3 $128,r0,-(sp)
pushal L191
calls $2,_debug
jbc $2,_tracer,L192
pushl $4
calls $1,_pflg
pushl 8(ap)
calls $1,_BlockStat
pushl r0
pushl 4(ap)
calls $1,_Pinfo
pushl r0
pushal L193
calls $3,_ptrace
L192:movl 4(ap),r0
cmpl 40(r0),8(ap)
jneq L194
pushl r0
calls $1,_timewrite
pushl 4(ap)
calls $1,_FreeMe
pushl 4(ap)
calls $1,_setrun
L194:ret
.align 1
.globl _EnterMe
.data
.align 2
L207:.double 0d2.56000000000000000000e+02
.text
.set L195,0xe00
.data
.text
_EnterMe:.word L195
subl2 $8,sp
movl 8(ap),r10
jbr L201
L2000006:movl 44(r10),r0
movl 4(ap),r1
cmpl 24(r0),24(r1)
jgeq L200
movl 44(r10),r10
L201:tstl 44(r10)
jneq L2000006
L200:movl r10,r9
movl $2,r11
jbr L204
L2000008:movl 44(r10),r0
movl 4(ap),r1
cmpl 24(r0),24(r1)
jneq L203
calls $0,_random
movzbl r0,r0
cvtld r0,-8(fp)
cvtld r11,r0
divd3 r0,L207,r2
cmpd -8(fp),r2
jgeq L202
movl 44(r10),r9
L202:movl 44(r10),r10
incl r11
L204:tstl 44(r10)
jneq L2000008
L203:movl 4(ap),r0
movl 44(r9),44(r0)
movl 4(ap),r0
movl r9,48(r0)
tstl 44(r9)
jeql L208
movl 44(r9),r0
movl 4(ap),48(r0)
L208:movl 4(ap),44(r9)
ret
.align 1
.globl _PriEnterMe
.set L209,0x800
.data
.text
_PriEnterMe:.word L209
movl 8(ap),r11
jbr L215
L2000010:movl 44(r11),r0
movl 4(ap),r1
cmpl 24(r0),24(r1)
jgtr L214
movl 44(r11),r11
L215:tstl 44(r11)
jneq L2000010
L214:movl 4(ap),r0
movl 44(r11),44(r0)
movl 4(ap),r0
movl r11,48(r0)
tstl 44(r11)
jeql L216
movl 44(r11),r0
movl 4(ap),48(r0)
L216:movl 4(ap),44(r11)
ret
.align 1
.globl _FreeMe
.set L217,0x800
.data
.text
_FreeMe:.word L217
movl 4(ap),r0
movl 44(r0),r11
tstl 48(r0)
jeql L221
movl 48(r0),r0
movl r11,44(r0)
L221:tstl r11
jeql L222
movl 4(ap),r0
movl 48(r0),48(r11)
L222:ret
.align 1
.globl _Deadlock
.data 1
L228:.ascii "deadlock\12\0"
.text
.data 1
L230:.ascii "process terminated successfully\12\0"
.text
.set L223,0x0
.data
.text
_Deadlock:.word L223
movl _waitq,r0
tstl 44(r0)
jeql L227
pushal L228
calls $1,_panic
L227:pushal L230
calls $1,_printf
pushl $0
calls $1,_exit
ret
.align 1
.globl _timesync
.data 1
L236:.ascii "[%d] time %d\12\0"
.text
.set L232,0x0
.data
.text
_timesync:.word L232
movl 4(ap),r0
movl r0,r1
addl3 112(r1),116(r0),r0
movl -4(r0),24(r1)
movl 4(ap),r0
pushl 24(r0)
subl3 $_proctable,_proc,r0
divl3 $128,r0,-(sp)
pushal L236
calls $3,_debug
ret
.align 1
.globl _timewrite
.set L237,0x0
.data
.text
_timewrite:.word L237
movl 4(ap),r0
movl r0,r1
movl r1,r2
addl3 112(r2),116(r1),r1
movl 24(r0),-4(r1)
ret
SHAR_EOF
fi # end of overwriting check
if test -f 'sysio.c'
then
echo shar: will not over-write existing file "'sysio.c'"
else
cat << \SHAR_EOF > 'sysio.c'
static char *rcsid = "$Header: sysio.c,v 3.3 86/11/03 12:35:14 gil Exp $";
#include <stdio.h>
#include "conf.h"
#include "process.h"
#include "chan.h"
#include <sys/uio.h>
#include <sys/ioctl.h>
#include <sys/file.h>
chtime(chid) {
Channel *ch;
ch = chanof(chid);
ch->ch_flags = CH_TIME;
time_ch = chid;
}
tread(ch, time)
Channel *ch;
int time;
{
register IoVec *iov;
IoBlock *blk;
blk = ch->ch_read.b_next;
for (iov = blk->b_data;
iov < &blk->b_data[blk->b_ndata];
iov++) {
if (iov->io_len != sizeof(blk->b_proc->p_time))
debug("time request is longword length\n");
*(int *)iov->io_data = time;
iov++;
}
ReadDone(ch, time);
return 1;
}
#ifdef S_SYS
/* allocate special time channel */
chassign(chid, fd, mode)
{
Channel *ch;
ch = chanof(chid);
ch->ch_flags = CH_SYS;
ch->ch_fd = fd;
if(isatty(fd))
ch->ch_flags := CH_DEV;
}
SysWrite(ch, time)
Channel *ch;
{
IoBlock *wblk;
IoVec *vv;
int l;
register i = 0, m;
int len;
wblk = ch->ch_write.b_next;
vv = wblk->b_data;
len = wblk->b_ndata;
for(i = 0; i < len; i++, vv++) {
m = vv->io_len;
vv->io_len = (int) vv->io_data;
vv->io_data = (char *) m;
}
if(writev(ch->ch_fd, wblk->b_data, len) < 0)
perror("writev");
NTRACE(TRACE_IO,
("[%d] write %d blocks, from %s (UNIX fd=%d)", chidof(ch),
len, Pinfo(wblk->b_proc), ch->ch_fd));
WriteDone(ch, time);
}
SysRead(ch, time)
Channel *ch;
{
IoBlock *rblk;
IoVec *vv;
int l;
register i = 0, m;
int len;
rblk = ch->ch_read.b_next;
vv = rblk->b_data;
len = rblk->b_ndata;
if(IsSpecialDevice(ch)) {
l = 0;
while(vv->io_len > 0 && l <= 0) {
ioctl(ch->ch_fd, FIONREAD, &l);
if(l <= 0)
swtch();
while(l > 0) {
m = min(l, vv->io_len);
read(ch->ch_fd, vv->io_data, m);
vv->io_data += m;
vv->io_len -= m;
l -= m;
if(vv->io_len == 0)
if(++i == len)
break;
else
vv++;
}
}
return;
}
for(i = 0; i < len; i++, vv++) {
m = vv->io_len;
vv->io_len = (int) vv->io_data;
vv->io_data = (char *) m;
}
if(readv(ch->ch_fd, rblk->b_data, len) < 0)
perror("readv");
NTRACE(TRACE_IO,
("[%d] read %d blocks, to %s (UNIX fd=%d)", chidof(ch),
len, Pinfo(rblk->b_proc), ch->ch_fd));
ReadDone(ch, time);
}
SpecialSelect() {
debug("Not implemented yet");
return 0;
}
#endif S_SYS
SHAR_EOF
fi # end of overwriting check
cd ..
# End of shell archive
exit 0
----------end of sim.shar----------
--
-
- Terry Torkelson Internet: ttork%ewu@uunet.uu.net
- Eastern Washington University uucp: uunet!isc-br!ewu!ttork
- tellynet: 509-359-6016
Technical Details
Message-ID:
<1338@ewu.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rutgers!apple!olivea!oliveb!isc-br!ewu!ttorkShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rutgers!apple!olivea!oliveb!isc-br!ewu!ttork From: ttork@ewu.UUCP (Terry Torkelson) Newsgroups: comp.sys.transputer Subject: Unix Occam Compiler Keywords: Occam Message-ID: <1338@ewu.UUCP> Date: 14 Nov 90 19:39:46 GMT Distribution: usa Organization: Eastern Washington Univ. Cheney WA Lines: 3113