Example #1
0
/*------------------------------------------------------------------------
 * getstk  --  allocate stack memory, returning address of topmost WORD
 *------------------------------------------------------------------------
 */
WORD *getstk(unsigned int nbytes)
{
	STATWORD ps;    
	struct	mblock	*p, *q;	/* q follows p along memlist		*/
	struct	mblock	*fits, *fitsq=NULL;
	WORD	len;

	disable(ps);
	if (nbytes == 0) {
		restore(ps);
		return( (WORD *)SYSERR );
	}
	nbytes = (unsigned int) roundew(nbytes);
	fits = (struct mblock *) NULL;
	q = &memlist;
	for (p = q->mnext ; p !=(struct mblock *) NULL ; q = p,p = p->mnext)
		if ( p->mlen >= nbytes) {
			fitsq = q;
			fits = p;
		}
	if (fits == (struct mblock *) NULL) {
		restore(ps);
		return( (WORD *)SYSERR );
	}
	if (nbytes == (len = fits->mlen) ) {
		fitsq->mnext = fits->mnext;
	} else {
		fits->mlen -= nbytes;
	}
	fits = (struct mblock *) ((WORD) fits + len - sizeof(WORD));
	*((WORD *) fits) = nbytes;
	restore(ps);
	return( (WORD *) fits);
}
Example #2
0
//procedure address
//stack size in words
//proccess priority > 0
//name (for debugging)
//number of args
//argments
SYSCALL create(int *procaddr,int ssize,int priority,char *name,int nargs,int args)
{
    int pid;            /* stores new process id    */
    struct  pentry  *pptr;      /* pointer to proc. table entry */
    int *saddr;         /* stack address        */
    sigset_t ps;            /* saved processor status   */
    disable(ps);
    ssize = roundew(ssize);
    pid = newpid();
    if ((ssize < MINSTK) || (pid == SYSERR) || (priority < 1))
    {
        restore(ps);
        return(SYSERR);
    }
    if ((int)(saddr = getstk(ssize)) == SYSERR)
    {
        proctab[pid].pstate=PRFREE; //free pid
        restore(ps);
        return(SYSERR);
    }

    numproc++;
    pptr = &proctab[pid];
    pptr->pstate = PRSUSP;
    strcpy(pptr->pname,name);
    pptr->pprio = priority;
    pptr->pbase = (int) saddr;
    pptr->pstklen = ssize;
    pptr->psem = 0;
    pptr->phasmsg = FALSE;
    pptr->plimit = (int)(saddr - ssize + 1);
    pptr->pargs = nargs;

    pptr->posix_ctxt = posix_ctxt_init;
    pptr->posix_ctxt.uc_stack.ss_size = ssize;
    pptr->posix_ctxt.uc_stack.ss_sp = (void*)((int) saddr - ssize + 1);
    pptr->posix_ctxt.uc_stack.ss_flags = 0;
    pptr->posix_ctxt.uc_link = &return_ctxt;
    switch (nargs)
    {
    case 0:
        makecontext(&(pptr->posix_ctxt),(void *)procaddr,0);
        break;
    case 1:
        makecontext(&(pptr->posix_ctxt),(void *)procaddr,1,args);
        break;
    case 2:
        makecontext(&(pptr->posix_ctxt),(void *)procaddr,2,args,*(&args+1));
        break;
    case 3:
        makecontext(&(pptr->posix_ctxt),(void *)procaddr,3,args,*(&args+1),*(&args+2));
        break;
    }

    restore(ps);
    return(pid);
}
Example #3
0
//------------------------------------------------------------------------
//  freemem  --  free a memory block, returning it to memlist
//------------------------------------------------------------------------
SYSCALL
freemem(void *b, size_t size)
{
    int ps;
    struct mblock *p, *prev, *block = (struct mblock *)b;
    intptr_t top;

    if (size == 0 ||
            (intptr_t)block > (intptr_t)maxaddr ||
            (intptr_t)block < (intptr_t)&end)
        return SYSERR;
    size = (size_t)roundew(size);
    ps = disable();
    for (p = memlist.mnext, prev = &memlist;
            p != NULL && p < block;
            prev = p, p = p->mnext);
    top = prev->mlen + (intptr_t)prev;
    if (top > (intptr_t)block &&
            (prev != &memlist || p != NULL) &&
            ((intptr_t)block + size) > (intptr_t)p) {
        restore(ps);
        return SYSERR;
    }
    if (prev != &memlist && top == (intptr_t)block)
        prev->mlen += size;
    else {
        block->mlen = size;
        block->mnext = p;
        prev->mnext = block;
        prev = block;
    }
    if ((prev->mlen + (intptr_t)prev) == (intptr_t)p) {
        prev->mlen += p->mlen;
        prev->mnext = p->mnext;
    }
    restore(ps);

    return OK;
}
/*------------------------------------------------------------------------
 *  create  -  create a process to start running a procedure
 *------------------------------------------------------------------------
 */
pid32	create_9_4(
	  void		*procaddr,	/* procedure address		*/
	  uint32	ssize,		/* stack size in words		*/
	  pri16		priority,	/* process priority > 0		*/
	  char		*name,		/* name (for debugging)		*/
	  uint32	nargs,		/* number of args that follow	*/
	  ...
	)
{
	uint32		savsp, *pushsp;
	intmask 	mask;    	/* interrupt mask		*/
	pid32		pid;		/* stores new process id	*/
	struct	procent	*prptr;		/* pointer to proc. table entry */
	int32		i;
	uint32		*a;		/* points to list of args	*/
	uint32		*saddr;		/* stack address		*/

	mask = disable();
	if (ssize < MINSTK)
		ssize = MINSTK;
	ssize = (uint32) roundew(ssize);
	if (((saddr = (uint32 *)getstk_new(ssize)) ==
	    (uint32 *)SYSERR ) ||
	    (pid=newpid()) == SYSERR || priority < 1 ) {
		restore(mask);
		return SYSERR;
	}

	prcount++;
	prptr = &proctab[pid];

	/* initialize process table entry for new process */
	prptr->prstate = PR_SUSP;	/* initial state is suspended	*/
	prptr->prprio = priority;
	prptr->prstkbase = (char *)saddr;
	prptr->prstklen = ssize;
	prptr->prname[PNMLEN-1] = NULLCH;
	for (i=0 ; i<PNMLEN-1 && (prptr->prname[i]=name[i])!=NULLCH; i++)
		;
	prptr->prsem = -1;
	prptr->prparent = (pid32)getpid();
	prptr->prhasmsg = FALSE;

	/* set up initial device descriptors for the shell		*/
	prptr->prdesc[0] = CONSOLE;	/* stdin  is CONSOLE device	*/
	prptr->prdesc[1] = CONSOLE;	/* stdout is CONSOLE device	*/
	prptr->prdesc[2] = CONSOLE;	/* stderr is CONSOLE device	*/

	/* Initialize stack as if the process was called		*/

	*saddr = STACKMAGIC;
	savsp = (uint32)saddr;

	/* push arguments */
	a = (uint32 *)(&nargs + 1);	/* start of args		*/
	a += nargs -1;			/* last argument		*/
	for ( ; nargs > 4 ; nargs--)	/* machine dependent; copy args	*/
		*--saddr = *a--;	/* onto created process' stack	*/
	*--saddr = (long)procaddr;
	for(i = 11; i >= 4; i--)
		*--saddr = 0;
	for(i = 4; i > 0; i--) {
		if(i <= nargs)
			*--saddr = *a--;
		else
			*--saddr = 0;
	}
	*--saddr = (long)INITRET;	/* push on return address	*/
	*--saddr = (long)0x00000053;	/* CPSR, A, F bits set,		*/
					/* Supervisor mode		*/
	prptr->prstkptr = (char *)saddr;
	restore(mask);
	return pid;

	/* The following entries on the stack must match what ctxsw	*/
	/*   expects a saved process state to contain: ret address,	*/
	/*   ebp, interrupt mask, flags, registerss, and an old SP	*/

	*--saddr = (long)procaddr;	/* Make the stack look like it's*/
					/*  half-way through a call to	*/
					/*  ctxsw that "returns" to the	*/
					/*  new process			*/
	*--saddr = savsp;		/* This will be register ebp	*/
					/*  for process exit		*/
	savsp = (uint32) saddr;		/* start of frame for ctxsw	*/
	*--saddr = 0x00000200;		/* New process runs with	*/
					/*  interrupts enabled		*/

	/* Basically, the following emulates a x86 "pushal" instruction	*/

	*--saddr = 0;		/* %eax */
	*--saddr = 0;		/* %ecx */
	*--saddr = 0;		/* %edx */
	*--saddr = 0;		/* %ebx */
	*--saddr = 0;		/* %esp; value filled in below */
	pushsp = saddr;		/*  remember this location */
	*--saddr = savsp;	/* %ebp (while finishing ctxsw) */
	*--saddr = 0;		/* %esi */
	*--saddr = 0;		/* %edi */
	*pushsp = (unsigned long) (prptr->prstkptr = (char *)saddr);
	restore(mask);
	return pid;
}
Example #5
0
//------------------------------------------------------------------------
//  sysinit  --  initialize all Xinu data structures and devices
//------------------------------------------------------------------------
static int
sysinit(void)
{
	static int (*nulluserp)() = &nulluser;
	static uword *nulluserpp = (uword *)&nulluserp;

	struct pentry *pptr;
	struct mblock *mptr;

	// initialize system variables
	numproc = 0;
	nextproc = NPROC - 1;
	nextsem = NSEM - 1;
	nextqueue = NPROC;	// q[0..NPROC-1] are processes

	// initialize free memory list
	memlist.mnext = mptr = (struct mblock *)roundew(&end);
	mptr->mnext = (struct mblock *)NULL;
	mptr->mlen = (uword)truncew((uintptr_t)maxaddr - NULLSTK - (uintptr_t)&end);

	// initialize process table
	for (int k = 0; k < NPROC; k++)
		proctab[k].pstate = PRFREE;

	// initialize null process entry
	pptr = &proctab[NULLPROC];
	pptr->pstate = PRCURR;
	pptr->pprio = 0;
	strlcpy(pptr->pname, "prnull", PNMLEN);
	pptr->plimit = ((char *)maxaddr) - NULLSTK - sizeof(uword);
	pptr->pbase = (char *)maxaddr;
	*((uword *)pptr->pbase) = MAGIC;
	pptr->paddr = (char *)(*nulluserpp);
	pptr->phasmsg = FALSE;
	pptr->pargs = 0;
	currpid = NULLPROC;

	// initialize semaphores
	for (int k = 0; k < NSEM; k++) {
		struct sentry *sptr = &semaph[k];
		sptr->sstate = SFREE;
		sptr->sqtail = 1 + (sptr->sqhead = newqueue());
	}

	// initialize ready list
	rdyhead = newqueue();
	rdytail = 1 + rdyhead;

	// initialize memory marking
	_mkinit();

	// initialize r.t.clock
	clkinit();

	// initialize disk buffers
	dskdbp = mkpool(DBUFSIZ, NDBUFF);
	dskrbp = mkpool(DREQSIZ, NDREQ);

	// initialize devices
	for (int k = 0; k < NDEVS; k++)
		init(k);

	return OK;
}
/*------------------------------------------------------------------------
 *  create  -  create a process to start running a procedure
 *------------------------------------------------------------------------
 */
SYSCALL create(int (*procaddr)(), int ssize, int priority, char *name,
		int nargs, ...)
{
	va_list		ap;
	unsigned long	savsp, *pushsp;
	STATWORD 	ps;    
	int		pid;		/* stores new process id	*/
	struct	pentry	*pptr;		/* pointer to proc. table entry */
	int		i;
	unsigned long	*saddr, *uarg;	/* stack address		*/
	unsigned long   *getstk();
	int		INITRET();

	va_start(ap, nargs);
	disable(ps);
	if (ssize < MINSTK)
		ssize = MINSTK;
	ssize = (int) roundew(ssize);
	if (((saddr = (unsigned long *)getstk(ssize)) ==
	    (unsigned long *)SYSERR ) ||
	    (pid=newpid()) == SYSERR || priority < 1 ) {
		restore(ps);
		va_end(ap);
		return SYSERR;
	}

	numproc++;
	pptr = &proctab[pid];

	pptr->fildes[0] = 0;	/* stdin set to console */
	pptr->fildes[1] = 0;	/* stdout set to console */
	pptr->fildes[2] = 0;	/* stderr set to console */

	for (i=3; i < _NFILE; i++)	/* others set to unused */
		pptr->fildes[i] = FDFREE;

	pptr->pstate = PRSUSP;
	for (i=0 ; i<PNMLEN && (int)(pptr->pname[i]=name[i])!=0 ; i++)
		;
	pptr->pprio = priority;
	pptr->pbase = (long) saddr;
	pptr->pstklen = ssize;
	pptr->psem = 0;
	pptr->phasmsg = FALSE;
	pptr->plimit = pptr->pbase - ssize + sizeof (long);	
	pptr->pirmask[0] = 0;
	pptr->pnxtkin = BADPID;
	pptr->pdevs[0] = pptr->pdevs[1] = BADDEV;

		/* Bottom of stack */
	*saddr = MAGIC;
	savsp = (unsigned long)saddr;

	/* push arguments */
	pptr->pargs = nargs;
	uarg = saddr - nargs;
	saddr = uarg;	/* end of args for after the copy */
	for (; nargs > 0 ; nargs--)
		*uarg++ = va_arg(ap, unsigned long);
	*--saddr = (long)INITRET;	/* push on return address	*/

	*--saddr = pptr->paddr = (long)procaddr; /* where we "ret" to	*/
	*--saddr = savsp;		/* fake frame ptr for procaddr	*/
	savsp = (unsigned long) saddr;

/* this must match what ctxsw expects: flags, regs, old SP */
/* emulate 386 "pushal" instruction */
	*--saddr = 0;
	*--saddr = 0;	/* %eax */
	*--saddr = 0;	/* %ecx */
	*--saddr = 0;	/* %edx */
	*--saddr = 0;	/* %ebx */
	*--saddr = 0;	/* %esp; fill in below */
	pushsp = saddr;
	*--saddr = savsp;	/* %ebp */
	*--saddr = 0;		/* %esi */
	*--saddr = 0;		/* %edi */
	*pushsp = pptr->pesp = (unsigned long)saddr;

	restore(ps);
	va_end(ap);
	return pid;
}