Example #1
0
void notmain ( void )
{
    PUT32(TRISECLR,0x1);
    PUT32(PORTESET,0x1);

    //insure PBDIV is 1:1
    PUT32(SYSKEY,0xAA996655);
    PUT32(SYSKEY,0x556699AA);
    PUT32(OSCCONCLR,0x180000);
    PUT32(SYSKEY,0x33333333);

    //use timer1 and set to divide by 1
    PUT32(T1CON,0x0000);
    PUT32(TMR1,0x0000);
    PUT32(PR1,0xFFFF);
    PUT32(T1CON,0x8000);

    while(1)
    {
        PUT32(PORTECLR,0x1);
        dowait();
        PUT32(PORTESET,0x1);
        dowait();
    }
}
/*
 * wait
 * allows the user to "foreground" a process by waiting on it.  without ps to
 * know the pids, this is a little tough to use with an arg, but without an
 * arg it will wait for all the background jobs.
 */
static
int
cmd_wait(int ac, char *av[])
{
	int i;
	pid_t pid;

	if (ac == 2) {
		pid = atoi(av[1]);
		dowait(pid);
		for (i = 0; i < MAXBG; i++) {
			if (bgpids[i]==pid) {
				bgpids[i] = 0;
			}
		}
		return 0;
	}
	else if (ac == 1) {
		for (i=0; i < MAXBG; i++) {
			if (bgpids[i] != 0) {
				dowait(bgpids[i]);
				bgpids[i] = 0;
			}
		}
		return 0;
	}
	printf("Usage: wait [pid]\n");
	return 1;
}
Example #3
0
//------------------------------------------------------------------------
void notmain ( void )
{
    //unsigned int ra;

    switch_to_80Mhz();

    uart_init();
    hexstring(0x87654321);
    hexstring(0x12345678);

    //Cortex-M4 systick timer init
    PUT32(STCTRL,0x00000004);
    PUT32(STRELOAD,1000000-1);
    PUT32(STCURRENT,0); //value is a dont care
    PUT32(STCTRL,0x00000005);

    while(1)
    {
        uart_send(0x55);
        dowait();
        uart_send(0x56);
        dowait();
    }

}
Example #4
0
int main()
{

    int pid0, pid1, pid2;

	pid0 = dofork();
	
	putchar('0');
	check();
	putchar('a');

	pid1 = dofork();
	putchar('1');
	check();
	putchar('b');

	pid2 = dofork();
	putchar('2');
	check();
	//putchar('c');

	dowait(pid2);
	dowait(pid1);
	dowait(pid0);

	putchar('\n');

	return 0;
}
Example #5
0
int
waitcmd(int argc, char **argv)
{
	struct job *job;
	int status, retval;
	struct job *jp;

	nextopt("");

	if (!*argptr) {
		/* wait for all jobs */
		jp = jobtab;
		if (jobs_invalid)
			return 0;
		for (;;) {
			if (jp >= jobtab + njobs) {
				/* no running procs */
				return 0;
			}
			if (!jp->used || jp->state != JOBRUNNING) {
				jp++;
				continue;
			}
			if (dowait(WBLOCK, NULL) == -1)
			       return 128 + SIGINT;
			jp = jobtab;
		}
	}

	retval = 127;		/* XXXGCC: -Wuninitialized */
	for (; *argptr; argptr++) {
		job = getjob(*argptr, 1);
		if (!job) {
			retval = 127;
			continue;
		}
		/* loop until process terminated or stopped */
		while (job->state == JOBRUNNING) {
			if (dowait(WBLOCK|WNOFREE, job) == -1)
			       return 128 + SIGINT;
		}
		status = job->ps[job->nprocs ? job->nprocs - 1 : 0].status;
		if (WIFEXITED(status))
			retval = WEXITSTATUS(status);
#if JOBS
		else if (WIFSTOPPED(status))
			retval = WSTOPSIG(status) + 128;
#endif
		else {
			/* XXX: limits number of signals */
			retval = WTERMSIG(status) + 128;
		}
		if (!iflag)
			freejob(job);
	}
	return retval;
}
Example #6
0
void notmain ( void )
{
    PUT32(0x50008000,GET32(0x50008000)|0x80);
    while(1)
    {
        PUT32(0x50000200,0x00000000);
        dowait();
        PUT32(0x50000200,0xFFFFFFFF);
        dowait();
    }
}
Example #7
0
/*
 * Allocate and then fork, in case fork doesn't preserve the heap.
 */
static
void
test13(void)
{
	pid_t pid;
	void *p;

	printf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt before forking");
	}

	printf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		exit(0);
	}
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent");
	}
	dowait(pid);
	printf("Passed sbrk test 13.\n");
}
Example #8
0
File: psort.c Project: BWK/os161
static
void
doforkall(const char *phasename, void (*func)(void))
{
	int i, bad = 0;
	pid_t pids[numprocs];

	for (i=0; i<numprocs; i++) {
		pids[i] = dofork();
		if (pids[i] < 0) {
			bad = 1;
		}
		else if (pids[i] == 0) {
			/* child */
			me = i;
			func();
			exit(0);
		}
	}

	for (i=0; i<numprocs; i++) {
		if (pids[i] > 0 && dowait(i, pids[i])) {
			bad = 1;
		}
	}

	if (bad) {
		complainx("%s failed.", phasename);
		exit(1);
	}
}
/*
 * Allocate, then fork, then free the allocated page in the child.
 */
static
void
test14(void)
{
	pid_t pid;
	void *p;

	tprintf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt before forking");
	}

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		tprintf("Child freeing a page...\n");
		dosbrk(-PAGE_SIZE);
		exit(0);
	}
	dowait(pid);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent after child ran");
	}
	tprintf("Passed sbrk test 14.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
Example #10
0
void
quint(const char *prog)
{
	pid_t pids[5];
	int i, failures = 0;
	char *args[2];

	/* set up the argv */
	args[0]=(char *)prog;
	args[1]=NULL;

	warnx("Starting: running five copies of %s...", prog);

	for (i=0; i<5; i++) {
		pids[i]=spawnv(args[0], args);
	}

	for (i=0; i<5; i++) {
		failures += dowait(i, pids[i]);
	}

	if (failures > 0) {
		warnx("%d failures", failures);
	}
	else {
		warnx("Congratulations! You passed.");
	}
}
/*
 * Fork and then allocate in both the parent and the child, in case
 * fork messes up the heap. Note: this is not intended to test the
 * parent and child running concurrently -- that should probably be
 * its own test program.
 */
static
void
test12(void)
{
	pid_t pid;
	void *p;

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		say("Child allocating a page...\n");
		p = dosbrk(PAGE_SIZE);
		markpage(p, 0);
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		say("Child done.\n");
		exit(0);
	}
	/* parent */
	say("Parent allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent");
	}
	say("Parent done.\n");
	dowait(pid);
	tprintf("Passed sbrk test 12.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
Example #12
0
static
void
basetest(void)
{
	unsigned i;
	struct usem gosems[NUMJOBS], waitsems[NUMJOBS];
	pid_t pids[NUMJOBS];

	for (i=0; i<NUMJOBS; i++) {
		usem_init(&gosems[i], "g", i);
		usem_init(&waitsems[i], "w", i);
	}

	for (i=0; i<NUMJOBS; i++) {
		pids[i] = fork();
		if (pids[i] < 0) {
			err(1, "fork");
		}
		if (pids[i] == 0) {
			child_with_own_fd(&gosems[i], &waitsems[i], i);
			_exit(0);
		}
	}
	baseparent(gosems, waitsems);

	for (i=0; i<NUMJOBS; i++) {
		dowait(pids[i], i);
	}

	for (i=0; i<NUMJOBS; i++) {
		usem_cleanup(&gosems[i]);
		usem_cleanup(&waitsems[i]);
	}
}
Example #13
0
int main()
{

        pid_p = getpid();
	//printf("value of pid_p after getpid is %d \n", pid_p);        
	putchar('w');
        pid_c = dofork();
	//printf("value of pid_c after getpid is %d \n", pid_c);    
        if (getpid() == pid_p) {
                check();
                dowait(pid_c);
        } else {
                putchar('e');
                _exit(0);
        }

        putchar('k');

        if (getpid() == pid_p)
                putchar('p');
        else 
                printf("wrong %d\n", getpid());

        putchar('\n');

	return 0;
}
Example #14
0
static
void
concur(void)
{
	int i, fd;
	int r1, r2, w1;

	printf("Spawning 2 readers, 1 writer.\n");


	fd = open(FNAME, O_WRONLY|O_CREAT|O_TRUNC, 0664);
	if (fd < 0) {
		err(1, "[CONCUR]: %s: open", FNAME);
	}

	printf("Initializing test file: ");

	for (i = 0; i < SECTOR_SIZE + 1; i++) {
		cbuffer[i] = READCHAR;
	}

	for (i = 0; i < TMULT; i++) {
		write(fd, cbuffer, SECTOR_SIZE + 1);
	}


	close(fd);

	printf("Done initializing. Starting processes...\n");

	r1 = forkoff(subproc_read);
	w1 = forkoff(subproc_write);
	r2 = forkoff(subproc_read);

	printf("Waiting for processes.\n");

	dowait(r1);
	dowait(r2);
	dowait(w1);

	if (remove(FNAME)) {
		err(1, "[CONCUR]: %s: remove", FNAME);
	}

	printf("[CONCUR] Done!\n");
}
Example #15
0
void
showjobs(struct output *out, int mode)
{
	int jobno;
	struct job *jp;
	int silent = 0, gotpid;

	TRACE(("showjobs(%x) called\n", mode));

	/* If not even one one job changed, there is nothing to do */
	gotpid = dowait(0, NULL);
	while (dowait(0, NULL) > 0)
		continue;
#ifdef JOBS
	/*
	 * Check if we are not in our foreground group, and if not
	 * put us in it.
	 */
	if (mflag && gotpid != -1 && tcgetpgrp(ttyfd) != getpid()) {
		if (tcsetpgrp(ttyfd, getpid()) == -1)
			error("Cannot set tty process group (%s) at %d",
			    strerror(errno), __LINE__);
		TRACE(("repaired tty process group\n"));
		silent = 1;
	}
#endif
	if (jobs_invalid)
		return;

	for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
		if (!jp->used)
			continue;
		if (jp->nprocs == 0) {
			freejob(jp);
			continue;
		}
		if ((mode & SHOW_CHANGED) && !jp->changed)
			continue;
		if (silent && jp->changed) {
			jp->changed = 0;
			continue;
		}
		showjob(out, jp, mode);
	}
}
Example #16
0
void notmain ( void )
{
    unsigned int ra;

    ra=GET32(RCGCGPIO);
    ra|=1<<12; //GPION
    PUT32(RCGCGPIO,ra);

    while(1)
    {
        if(GET32(PRGPIO)&(1<<12)) break;
    }

    //LEDs on PN0 and PN1

    ra=GET32(GPIONDIR);
    ra|=(1<<1)|(1<<0);
    PUT32(GPIONDIR,ra);

    //should already be 0
    ra=GET32(GPIONAFSEL);
    ra&=~((1<<1)|(1<<0));
    PUT32(GPIONAFSEL,ra);

    ra=GET32(GPIONODR);
    ra&=~((1<<1)|(1<<0));
    PUT32(GPIONODR,ra);

    ra=GET32(GPIONDEN);
    ra|=(1<<1)|(1<<0);
    PUT32(GPIONDEN,ra);

    for(ra=0;ra<10;ra++)
    //while(1)
    {
        PUT32(GPIONDATA|(((1<<1)|(1<<0))<<2),0xFF);
        dowait();
        PUT32(GPIONDATA|(((1<<1)|(1<<0))<<2),0x00);
        dowait();
    }

}
Example #17
0
int
waitforjob(struct job *jp)
{
#if JOBS
	int mypgrp = getpgrp();
#endif
	int status;
	int st;

	INTOFF;
	TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
	while (jp->state == JOBRUNNING) {
		dowait(WBLOCK, jp);
	}
#if JOBS
	if (jp->jobctl) {
		if (tcsetpgrp(ttyfd, mypgrp) == -1)
			error("Cannot set tty process group (%s) at %d",
			    strerror(errno), __LINE__);
	}
	if (jp->state == JOBSTOPPED && curjob != jp - jobtab)
		set_curjob(jp, 2);
#endif
	status = jp->ps[jp->nprocs - 1].status;
	/* convert to 8 bits */
	if (WIFEXITED(status))
		st = WEXITSTATUS(status);
#if JOBS
	else if (WIFSTOPPED(status))
		st = WSTOPSIG(status) + 128;
#endif
	else
		st = WTERMSIG(status) + 128;
	TRACE(("waitforjob: job %d, nproc %d, status %x, st %x\n",
		jp - jobtab + 1, jp->nprocs, status, st ));
#if JOBS
	if (jp->jobctl) {
		/*
		 * This is truly gross.
		 * If we're doing job control, then we did a TIOCSPGRP which
		 * caused us (the shell) to no longer be in the controlling
		 * session -- so we wouldn't have seen any ^C/SIGINT.  So, we
		 * intuit from the subprocess exit status whether a SIGINT
		 * occurred, and if so interrupt ourselves.  Yuck.  - mycroft
		 */
		if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
			raise(SIGINT);
	}
#endif
	if (! JOBS || jp->state == JOBDONE)
		freejob(jp);
	INTON;
	return st;
}
Example #18
0
////
// gender_one
//
//
//
void gender_one (char *exec, int id, int *line, int mutex, int depends,
                 int group, int reproducing, int raising) {
   int one = 0; // hide misleading index number
   int gathered; // shared variable
   FILE *fp; // file pointer for gathered shared variable file
   // print entering waiting state
   printf ("alien %d of gender 1 beginning to wait in line\n", id);
   // begin sleeping for random time
   dowait (1);
   //
   semdown (line[one]); // line_1.down()
   semdown (group); // group.down()
   semdown (mutex); // mutex.down()
   // get the shared gathered variable from "aliengathvar"
   fp = fopen ("aliengathvar", "r");
   // print error if could not open file successfully
   if (fp < 0 || fp == NULL) {
      fprintf (stderr, "%s: %s: failed to open aliengathvar\n", exec, "ERROR");
      exit (-1);
   }
   fscanf (fp, "%d", &gathered); // scan shared variable
   fclose (fp); // close read file
   // increment gathered
   gathered += 1;
   // check if the last of three gender residents necessary to reproduce
   if (gathered == 3) {
      gathered = 0; // attained group size so reset
      semdown (reproducing); // one of two groups to begin reproducing
      // all three have "reached" barrier
      semup (depends);
      semup (depends);
      semup (depends);
   }
   // write the shared variable gathered to "aliengathvar"
   fp = fopen ("aliengathvar", "w");
   if (fp < 0 || fp == NULL) {
      fprintf (stderr, "%s: %s: failed to open aliengathvar\n", exec, "ERROR");
      exit (-1);
   }
   fprintf (fp, "%d\n", gathered); // write shared variable
   fclose (fp); // close write file
   //
   semup (mutex); // mutex.up()
   semdown (depends); // depends.down()
   semup (group); // group.up()
   // print entering reproducing state
   printf ("alien %d of gender 1 beginning to reproduce\n", id);
   // hit sleeping barrier
   semdown (raising); // raising.down()
   printf ("%s %d of gender 1: leaving nursery\n", "alien", id); // leaving nursery
}
Example #19
0
File: jobs.c Project: 0xffea/MINIX3
int
waitcmd(int argc, char **argv)
{
	struct job *job;
	int status, retval;
	struct job *jp;

	if (argc > 1) {
		job = getjob(argv[1]);
	} else {
		job = NULL;
	}

	/*
	 * Loop until a process is terminated or stopped, or a SIGINT is
	 * received.
	 */

	in_waitcmd++;
	do {
		if (job != NULL) {
			if (job->state) {
				status = job->ps[job->nprocs - 1].status;
				if (WIFEXITED(status))
					retval = WEXITSTATUS(status);
#if JOBS
				else if (WIFSTOPPED(status))
					retval = WSTOPSIG(status) + 128;
#endif
				else
					retval = WTERMSIG(status) + 128;
				if (! iflag)
					freejob(job);
				in_waitcmd--;
				return retval;
			}
		} else {
			for (jp = jobtab ; ; jp++) {
				if (jp >= jobtab + njobs) {	/* no running procs */
					in_waitcmd--;
					return 0;
				}
				if (jp->used && jp->state == 0)
					break;
			}
		}
	} while (dowait(1, (struct job *)NULL) != -1);
	in_waitcmd--;

	return 0;
}
Example #20
0
void notmain ( void )
{
    unsigned int ra,rb,rc,rd,re,rf;

    clock_init();

    ra=GET32(GPIO_DIR1);
    ra|=1<<8;
    ra|=1<<9;
    ra|=1<<10;
    ra|=1<<11;
    PUT32(GPIO_DIR1,ra);

    PUT32(STCTRL,0x00000004); //disabled, no ints, use cpu clock
    PUT32(STRELOAD,12000000-1);
    PUT32(STCTRL,0x00000005); //enabled, no ints, use cpu clock

    ra=GPIO_SET1;
    rb=GPIO_CLR1;
    rc=1<<8;
    rd=1<<9;
    re=1<<10;
    rf=1<<11;

    while(1)
    {
        PUT32(ra,rc);
        PUT32(rb,rd);
        PUT32(rb,re);
        PUT32(rb,rf);
        dowait();
        PUT32(rb,rc);
        PUT32(ra,rd);
        PUT32(rb,re);
        PUT32(rb,rf);
        dowait();
        PUT32(rb,rc);
        PUT32(rb,rd);
        PUT32(ra,re);
        PUT32(rb,rf);
        dowait();
        PUT32(rb,rc);
        PUT32(rb,rd);
        PUT32(rb,re);
        PUT32(ra,rf);
        dowait();
        PUT32(rb,rc);
        PUT32(rb,rd);
        PUT32(ra,re);
        PUT32(rb,rf);
        dowait();
        PUT32(rb,rc);
        PUT32(ra,rd);
        PUT32(rb,re);
        PUT32(rb,rf);
        dowait();
    }
}
Example #21
0
/*
 * Do a task group: fork the processes, then wait for them.
 */
static
void
runtaskgroup(unsigned count,
	     void (*prep)(unsigned, unsigned),
	     void (*task)(unsigned, unsigned),
	     void (*cleanup)(unsigned, unsigned),
	     unsigned groupid)
{
	pid_t mypids[count];
	unsigned i;
	unsigned failures = 0;
	time_t secs;
	unsigned long nsecs;

	prep(groupid, count);

	for (i=0; i<count; i++) {
		mypids[i] = fork();
		if (mypids[i] < 0) {
			err(1, "fork");
		}
		if (mypids[i] == 0) {
			/* child (of second fork) */
			task(groupid, i);
			exit(0);
		}
		/* parent (of second fork) - continue */
	}

	/*
	 * now wait for the task to finish
	 */

	for (i=0; i<count; i++) {
		failures += dowait(mypids[i]);
	}

	/*
	 * Store the end time.
	 */

	__time(&secs, &nsecs);
	openresultsfile(O_WRONLY);
	putresult(groupid, secs, nsecs);
	closeresultsfile();

	cleanup(groupid, count);

	exit(failures ? 1 : 0);
}
Example #22
0
/*
 * Wait for the task group directors to exit.
 */
static
void
waitall(pid_t *pids, unsigned numpids)
{
	unsigned failures = 0;
	unsigned i;

	for (i=0; i<numpids; i++) {
		failures += dowait(pids[i]);
	}
	if (failures) {
		errx(1, "TEST FAILURE: one or more subprocesses broke");
	}
}
Example #23
0
/*
 * Actually run the test.
 */
static
void
test(int nowait)
{
	int pid0, pid1, pid2, pid3;

	/*
	 * Caution: This generates processes geometrically.
	 *
	 * It is unrolled to encourage gcc to registerize the pids,
	 * to prevent wait/exit problems if fork corrupts memory.
	 */

	pid0 = dofork();
	putchar('0');
	check();
	pid1 = dofork();
	putchar('1');
	check();
	pid2 = dofork();
	putchar('2');
	check();
	pid3 = dofork();
	putchar('3');
	check();

	/*
	 * These must be called in reverse order to avoid waiting
	 * improperly.
	 */
	dowait(nowait, pid3);
	dowait(nowait, pid2);
	dowait(nowait, pid1);
	dowait(nowait, pid0);

	putchar('\n');
}
Example #24
0
void RWLTaskProcessor::run() {
	while (true) {
		
		switch (state_) {
			case START: printf("status: START\n"); dostart(); break;
			case WAIT: printf("status: WAIT\n"); dowait(); break;
			case GMCW: printf("status: GMCW\n"); dogmcw(); break;
			case RWCWXZ: printf("status: RWCWXZ\n"); dorwcwxz(); break;
			case RWWPXZ: printf("status: RWWPXZ\n"); dorwwpxz(); break;
			case SHOPPING: printf("status: SHOPPING\n"); doshopping(); break;
			case STOP: printf("status: STOP\n"); return;
		}
		Sleep(5000);
	}
}
Example #25
0
static
void
dotest(void)
{
	unsigned i, me;
	pid_t pids[BRANCHES];
	int t;

	me = 0;
	for (i=0; i<BRANCHES; i++) {
		pids[i] = dofork();
		if (pids[i] == 0) {
			me += 1U<<i;
		}
		grind();
		t = trace();
		if (t == right[i]) {
			tsay("Stage %u #%u done: %d\n", i, me, trace());
		}
		else {
			tsay("Stage %u #%u FAILED: got %d, expected %d\n",
				 i, me, t, right[i]);
			success(TEST161_FAIL, SECRET, "/testbin/bigfork");
			failures++;
		}
		TEST161_TPROGRESS(0);
	}

	for (i=BRANCHES; i-- > 0; ) {
		dowait(pids[i]);
	}

	if (failures > 0) {
		tprintf("%u failures.\n", failures);
		success(TEST161_FAIL, SECRET, "/testbin/bigfork");
	}
	else {
		tprintf("Done.\n");
		success(TEST161_SUCCESS, SECRET, "/testbin/bigfork");
	}
}
Example #26
0
static
void
conctest(void)
{
	unsigned i;
	struct usem gosems[NUMJOBS], waitsems[NUMJOBS];
	pid_t pids[NUMJOBS];

	say("Shoot...\n");

	for (i=0; i<NUMJOBS; i++) {
		usem_init(&gosems[i], "g", i);
		usem_init(&waitsems[i], "w", i);
		usem_open(&gosems[i]);
		usem_open(&waitsems[i]);
	}

	for (i=0; i<NUMJOBS; i++) {
		pids[i] = fork();
		if (pids[i] < 0) {
			err(1, "fork");
		}
		if (pids[i] == 0) {
			child_plain(&gosems[i], &waitsems[i], i);
			_exit(0);
		}
	}
	concparent(gosems, waitsems);

	for (i=0; i<NUMJOBS; i++) {
		dowait(pids[i], i);
	}

	for (i=0; i<NUMJOBS; i++) {
		usem_close(&gosems[i]);
		usem_close(&waitsems[i]);
		usem_cleanup(&gosems[i]);
		usem_cleanup(&waitsems[i]);
	}
}
Example #27
0
File: jobs.c Project: 0xffea/MINIX3
void
showjobs(int change, int sformat, int lformat)
{
	int jobno;
	struct job *jp;

	TRACE(("showjobs(%d) called\n", change));
	while (dowait(0, (struct job *)NULL) > 0);
	for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
		if (! jp->used)
			continue;
		if (jp->nprocs == 0) {
			freejob(jp);
			continue;
		}
		if (change && ! jp->changed)
			continue;
		showjob(jp, 0, sformat, lformat);
		jp->changed = 0;
		if (jp->state == JOBDONE) {
			freejob(jp);
		}
	}
}
Example #28
0
/*
 * Performs the exec argument processing, all  of the child forking and
 * execing, and child cleanup.
 * Sets exitcode to non-zero if any errors occurred.
 */
void
do_mounts(void)
{
	int 		i, isave, cnt;
	vfsent_t 	*vp, *vpprev, **vl;
	char		*newargv[ARGV_MAX];
	pid_t		child;

	/*
	 * create the arg list once;  the only differences among
	 * the calls are the options, special and mountp fields.
	 */
	i = 2;
	if (cflg)
		newargv[i++] = "-c";
	if (gflg)
		newargv[i++] = "-g";
	if (mflg)
		newargv[i++] = "-m";
	if (Oflg)
		newargv[i++] = "-O";
	if (qflg)
		newargv[i++] = "-q";
	if (rflg)
		newargv[i++] = "-r";
	if (dashflg)
		newargv[i++] = "--";
	if (oflg) {
		newargv[i++] = "-o";
		newargv[i++] = specific_opts;
	}
	isave = i;

	/*
	 * Main loop for the mount processes
	 */
	vl = vfsarray;
	cnt = vfsarraysize;
	for (vpprev = *vl; vp = *vl; vpprev = vp, vl++, cnt--) {
		/*
		 * Check to see if we cross a mount level: e.g.,
		 * /a/b -> /a/b/c.  If so, we need to wait for all current
		 * mounts to finish, rerun realpath on the remaining mount
		 * points, and resort the list.
		 *
		 * Also, we mount serially as long as there are lofs's
		 * to mount to avoid improper mount ordering.
		 */
		if (vp->mlevel > vpprev->mlevel || lofscnt > 0) {
			vfsent_t **vlp;

			while (nrun > 0 && (dowait() != -1))
				;
			/*
			 * Gads! It's possible for real path mounts points to
			 * change after mounts are done at a lower mount
			 * level.
			 * Thus, we need to recalculate mount levels and
			 * resort the list from this point.
			 */
			for (vlp = vl; *vlp; vlp++)
				(void) setrpath(*vlp);
			/*
			 * Sort the remaining entries based on their newly
			 * resolved path names.
			 * Do not sort if we still have lofs's to mount.
			 */
			if (lofscnt == 0) {
				qsort((void *)vl, cnt, sizeof (vfsent_t *),
				    mlevelcmp);
				vp = *vl;
			}
		}

		if (vp->flag & VRPFAILED) {
			fprintf(stderr, gettext(
			    "%s: Nonexistent mount point: %s\n"),
			    myname, vp->v.vfs_mountp);
			vp->flag |= VNOTMOUNTED;
			exitcode = 1;
			continue;
		}

		/*
		 * If mount options were not specified on the command
		 * line, then use the ones found in the vfstab entry,
		 * if any.
		 */
		i = isave;
		if (!oflg && vp->v.vfs_mntopts) {
			newargv[i++] = "-o";
			newargv[i++] = vp->v.vfs_mntopts;
		}
		newargv[i++] = vp->v.vfs_special;
		newargv[i++] = vp->rpath;
		newargv[i] = NULL;

		/*
		 * This should never really fail.
		 */
		while (setup_iopipe(vp) == -1 && (dowait() != -1))
			;

		while (nrun >= maxrun && (dowait() != -1))	/* throttle */
			;

		if ((child = fork()) == -1) {
			perror("fork");
			cleanup(-1);
			/* not reached */
		}
		if (child == 0) {		/* child */
			signal(SIGHUP, SIG_IGN);
			signal(SIGQUIT, SIG_IGN);
			signal(SIGINT, SIG_IGN);
			setup_output(vp);
			doexec(vp->v.vfs_fstype, newargv);
			perror("exec");
			exit(1);
		}

		/* parent */
		(void) close(vp->sopipe[WRPIPE]);
		(void) close(vp->sepipe[WRPIPE]);
		vp->pid = child;
		nrun++;
	}
	/*
	 * Mostly done by now - wait and clean up the stragglers.
	 */
	cleanup(0);
}
Example #29
0
/* Return 0 if all processes are terminated, -1 on error, -2 on timeout. */
int process_wait(process_info_t* vec, int n, int timeout) {
  int i;
  process_info_t* p;
  dowait_args args;
  args.vec = vec;
  args.n = n;
  args.pipe[0] = -1;
  args.pipe[1] = -1;

  /* The simple case is where there is no timeout */
  if (timeout == -1) {
    dowait(&args);
    return 0;
  }

  /* Hard case. Do the wait with a timeout.
   *
   * Assumption: we are the only ones making this call right now. Otherwise
   * we'd need to lock vec.
   */

  pthread_t tid;
  int retval;

  int r = pipe((int*)&(args.pipe));
  if (r) {
    perror("pipe()");
    return -1;
  }

  r = pthread_create(&tid, NULL, dowait, &args);
  if (r) {
    perror("pthread_create()");
    retval = -1;
    goto terminate;
  }

  struct timeval tv;
  tv.tv_sec = timeout / 1000;
  tv.tv_usec = 0;

  fd_set fds;
  FD_ZERO(&fds);
  FD_SET(args.pipe[0], &fds);

  r = select(args.pipe[0] + 1, &fds, NULL, NULL, &tv);

  if (r == -1) {
    perror("select()");
    retval = -1;

  } else if (r) {
    /* The thread completed successfully. */
    retval = 0;

  } else {
    /* Timeout. Kill all the children. */
    for (i = 0; i < n; i++) {
      p = (process_info_t*)(vec + i * sizeof(process_info_t));
      kill(p->pid, SIGTERM);
    }
    retval = -2;

    /* Wait for thread to finish. */
    r = pthread_join(tid, NULL);
    if (r) {
      perror("pthread_join");
      retval = -1;
    }
  }

terminate:
  close(args.pipe[0]);
  close(args.pipe[1]);
  return retval;
}
/*
 * Allocate and free in both the parent and the child, and do more
 * than one page.
 */
static
void
test15(void)
{
	unsigned num = 12;

	pid_t pid;
	unsigned i;
	void *p;

	tprintf("Allocating %u pages...\n", num);
	p = dosbrk(PAGE_SIZE * num);
	for (i=0; i<num; i++) {
		markpage(p, i);
	}
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking");
		}
	}

	tprintf("Freeing one page...\n");
	(void)dosbrk(-PAGE_SIZE);
	num--;
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking (2)");
		}
	}

	tprintf("Allocating two pages...\n");
	(void)dosbrk(PAGE_SIZE * 2);
	markpage(p, num++);
	markpage(p, num++);
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking (3)");
		}
	}

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child");
			}
		}

		say("Child: freeing three pages\n");
		dosbrk(-PAGE_SIZE * 3);
		num -= 3;
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child (2)");
			}
		}

		say("Child: allocating two pages\n");
		dosbrk(PAGE_SIZE * 2);
		markpage(p, num++);
		markpage(p, num++);
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child (3)");
			}
		}

		say("Child: freeing all\n");
		dosbrk(-PAGE_SIZE * num);
		exit(0);
	}
	say("Parent: allocating four pages\n");
	dosbrk(PAGE_SIZE * 4);
	for (i=0; i<4; i++) {
		markpage(p, num++);
	}
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt in parent");
		}
	}

	say("Parent: waiting\n");
	dowait(pid);

	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt after waiting");
		}
	}

	(void)dosbrk(-PAGE_SIZE * num);
	tprintf("Passed sbrk test 15.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");

}