|
|
1.1 root 1: /* create.c - create, newpid */
2:
3: #include <conf.h>
4: #include <kernel.h>
5: #include <proc.h>
6: #include <mem.h>
7:
8: /*------------------------------------------------------------------------
9: * create - create a process to start running a procedure
10: *------------------------------------------------------------------------
11: */
12: SYSCALL create(procaddr,ssize,priority,name,nargs,args)
13: int *procaddr; /* procedure address */
14: int ssize; /* stack size in bytes */
15: int priority; /* process priority > 0 */
16: char *name; /* name (for debugging) */
17: int nargs; /* number of args that follow */
18: int args; /* arguments (treated like an */
19: /* array in the code) */
20: {
21: int pid; /* stores new process id */
22: struct pentry *pptr; /* pointer to proc. table entry */
23: int i;
24: int *a; /* points to list of args */
25: int *saddr; /* stack address */
26: int INITRET(); /* process return point */
27: PStype ps; /* saved processor status */
28:
29: disable(ps);
30: ssize = (int) roundew(ssize);
31: if ( ssize<MINSTK || ((saddr=(int *)getstk(ssize))==(int *)SYSERR ) ||
32: (pid=newpid()) == SYSERR || isodd(procaddr) ||
33: priority < 1 ) {
34: restore(ps);
35: return(SYSERR);
36: }
37: numproc++;
38: pptr = &proctab[pid];
39: pptr->pstate = PRSUSP;
40: for (i=0 ; i<PNMLEN && (pptr->pname[i]=name[i])!=0 ; i++)
41: ;
42: pptr->pprio = priority;
43: pptr->pbase = (int)saddr;
44: pptr->pstklen = ssize;
45: pptr->psem = 0;
46: pptr->phasmsg = FALSE;
47: pptr->plimit = (int) ((unsigned)saddr - ssize + sizeof(int));
48: *saddr-- = MAGIC;
49: pptr->pargs = nargs;
50: for (i=0 ; i<PNREGS ; i++) /* init pcb register entries */
51: pptr->pregs[i]=INITREG;
52: /* move PC past entry mask */
53: pptr->pregs[PCINDX] = pptr->paddr = (int)procaddr + sizeof(short);
54: pptr->pregs[PSINDX] = INITPS;
55: pptr->pregs[P0BRINDX] = pptr->pregs[P1BRINDX] = INITBR;
56: pptr->pregs[P0LRINDX] = INITLR;
57: pptr->pnxtkin = BADPID;
58: /* simulate stack of CALLG w/o */
59: /* any registers saved (mask==0)*/
60: a = (&args) + (nargs-1); /* point to last argument */
61: for ( ; nargs > 0 ; nargs--) /* machine dependent; copy args */
62: *saddr-- = *a--; /* onto created process' stack */
63: *saddr = (int)INITRET+sizeof(short);/* push return address */
64: /* ret to INITRET, past entry mask*/
65: pptr->pregs[APINDX]= (int)saddr;/* AP points to location on */
66: /* stack of 1st arg, -4 bytes */
67: for (i=0; i<PNRETPOP; i++) /* push values RET pops other */
68: *--saddr = INITREG; /* than PC (FP,AP,mask&PSW) */
69: pptr->pregs[SPINDX] = pptr->pregs[FPINDX] = (int)saddr;
70: restore(ps);
71: return(pid);
72: }
73:
74: /*------------------------------------------------------------------------
75: * newpid -- obtain a new (free) process id
76: *------------------------------------------------------------------------
77: */
78: LOCAL newpid()
79: {
80: int pid; /* process id to return */
81: int i;
82:
83: for (i=0 ; i<NPROC ; i++) { /* check all NPROC slots */
84: if ( (pid=nextproc--) <= 0)
85: nextproc = NPROC-1;
86: if (proctab[pid].pstate == PRFREE)
87: return(pid);
88: }
89: return(SYSERR);
90: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.