⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 四皇后问题
💻 C
字号:
/*
	Little Smalltalk

		process manager
		dennis a. vadner and michael t. benhase, 11/84
		modified by timothy a. budd 4/85
*/
/*
	The source code for the Little Smalltalk System may be freely
	copied provided that the source of all files is acknowledged
	and that this condition is copied with each file.

	The Little Smalltalk System is distributed without responsibility
	for the performance of the program and without any guarantee of
	maintenance.

	All questions concerning Little Smalltalk should be addressed to:

		Professor Tim Budd
		Department of Computer Science
		Oregon State University
		Corvallis, Oregon
		97331
		USA
*/

# include "object.h"

# include <stdio.h>

# ifdef SIGS
# include <signal.h>
# endif

# ifdef SETJUMP
# include <setjmp.h>
# endif

# include "drive.h"
# include "interp.h"
# include "process.h"

extern int  test_driver();	/* routine to test for user keystrokes*/

static process  *currentProcess;	/* current process */
static process  *fr_process = 0;	/* process memory free list */

int  atomcnt = 0;			/* atomic action flag */
process  *runningProcess;		/* currently running process,
					   may be different from
					   currentProcess during process
					   termination */

# define PROCINITMAX 6
static process prcinit[PROCINITMAX];	/* initial process free list */


/* init_process - initialize the process module */
init_process ()
{	process *p;
	int i;

	/* first make the initial process free list */
	for (p = prcinit, i = 0; i < PROCINITMAX; i++, p++) {
		p->next = fr_process;
		fr_process = p;
		}

	/* make the process associated with the driver */
	currentProcess = cr_process(o_drive);
	assign(currentProcess->next, currentProcess);
	assign(currentProcess->prev, currentProcess);
	currentProcess->p_state = ACTIVE;
}

/* cr_process - create a new process with the given interpreter */
process  *cr_process (anInterpreter)
interpreter  *anInterpreter;
{	process  *new;

	if (fr_process) {
	    new = (process *) fr_process;
	    fr_process = fr_process->next;
	    }
	else
	    new = structalloc(process);

	new->p_ref_count = 0;
	new->p_size = PROCSIZE;

	sassign(new->interp, anInterpreter);
	new->p_state = SUSPENDED;
	sassign(new->next, (process *) o_nil);
	sassign(new->prev, (process *) o_nil);

	return(new);
}


/* free_process - return an unused process to free list */
free_process (aProcess)
process  *aProcess;
{
	obj_dec((object *) aProcess->interp);
	obj_dec((object *) aProcess->next);
	obj_dec((object *) aProcess->prev);
	aProcess->p_state = TERMINATED;
	aProcess->next = fr_process;
	fr_process = aProcess;
}

/* flush_processes - flush out any remaining process from queue */
flush_processes ()
{
	while (currentProcess != currentProcess->next)
	   remove_process(currentProcess);

	/* prev link and next link should point to the same place now.
	   In order to avoid having memory recovered while we are
	   manipulating pointers, we increment reference count, then change
	   pointers, then decrement reference counts */

	obj_inc((object *) currentProcess);
	safeassign(currentProcess->prev, (process *) o_nil);
	safeassign(currentProcess->next, (process *) o_nil);
	obj_dec((object *) currentProcess);
}


/* link_to_process - change the interpreter for the current process */
link_to_process (anInterpreter)
interpreter  *anInterpreter;
{	object *temp;

	safeassign(runningProcess->interp, anInterpreter);
}


/* remove_process - remove a process from process queue */
static remove_process (aProcess)
process  *aProcess;
{
	if (aProcess == aProcess->next)
	    cant_happen(15);		/* removing last active process */

	/* currentProcess must always point to a process that is on the
	   process queue, make sure this remains true */

	if (aProcess == currentProcess)
	    currentProcess = currentProcess->prev;

	/* In order to avoid having memory recovered while we are changing
	pointers, we increment the reference counts on both processes,
	change pointers, then decrement reference counts */

	obj_inc((object *) currentProcess); obj_inc((object *) aProcess);
	safeassign(aProcess->next->prev, aProcess->prev);
	safeassign(aProcess->prev->next, aProcess->next);
	obj_dec((object *) currentProcess); obj_dec((object *) aProcess);
}


/* schedule_process - add a new process to the process queue */
static schedule_process (aProcess)
process  *aProcess;
{
	safeassign(aProcess->next, currentProcess);
	safeassign(aProcess->prev, currentProcess->prev);
	safeassign(aProcess->prev->next, aProcess);
	safeassign(currentProcess->prev, aProcess);
}

/* set_state - set the state on a process, which may involve inserting or
removing it from the process queue */
int  set_state (aProcess, state)
process  *aProcess;
int  state;
{
	switch (state) {
	    case BLOCKED:
	    case SUSPENDED:
	    case TERMINATED:	if (aProcess->p_state == ACTIVE)
				    remove_process(aProcess);
				aProcess->p_state |= state;
				break;

	    case READY:
	    case UNBLOCKED:	if ((aProcess->p_state ^ state) == ~ACTIVE)
				    schedule_process(aProcess);
				aProcess->p_state &= state;
				break;

	    case CUR_STATE:	break;
	    default:		cant_happen(17);
	    }
	return(aProcess->p_state);
}

# ifdef SETJUMP
static jmp_buf intenv;
# endif

/* brkfun - what to do on a break key */
brkfun()
{	static int warn = 1;

# ifndef SETJUMP
	exit(1);
# endif
	if (warn) {
		fprintf(stderr,"warning: recovery from interrupt may cause\n");
		fprintf(stderr,"reference counts to be incorrect, and\n");
		fprintf(stderr,"some memory to be inaccessible\n");
		warn = 0;
		}
# ifdef SETJUMP
	longjmp(intenv, 1);
# endif
}

/* start_execution - main execution loop */
start_execution ()
{	interpreter  *presentInterpreter;

	atomcnt = 0;

# ifdef SIGS
	/* trap user interrupt signals and recover */
	signal(SIGINT, brkfun);
# endif

# ifdef SETJUMP
	if (setjmp(intenv)) {
		atomcnt = 0;
		link_to_process(o_drive);
		}
# endif

	while (1) {
	    /* unless it is an atomic action get the next process */
	    if (! atomcnt)
		runningProcess = currentProcess = currentProcess->next;

	    if (! is_driver(runningProcess->interp)) {
		sassign(presentInterpreter, runningProcess->interp);
		resume(presentInterpreter);
		obj_dec((object *) presentInterpreter);
		}
	    else if (! test_driver((currentProcess == currentProcess->next) ||
				   (atomcnt > 0)))
		break;
	    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -