コード例 #1
0
ファイル: ioreq.c プロジェクト: rit-sos/SOS
void _ioreq_handle_idle_request(Drive *d){
	Status status;
	Key key;
	Iorequest *req;

	key.v = (void *) d;
	status = _q_remove_by_key( idle_q, (void **) &req, key );
	if(status == NOT_FOUND || status == EMPTY_QUEUE){
		d->state=IDLE;
		req = NULL; //wasn't found
		return;
	} else if (status != SUCCESS){
		_kpanic("handle_idle_request", "remove status", status);
	}

	if (! (_ata_pio_read_status(d) & (BSY | DRQ)) ){
		if (req->read){
			//send read request and add the data queue
			d->state=READING;
			req->st = WAIT_ON_DATA;
			_q_insert(data_q, (void *) req, key);
			_ata_pio_send_read(req->fd->device_data);
		} else {
			//transfer data and send write reqest
			d->state=WRITING;
			_ata_pio_send_write(req->fd->device_data);
			_ata_pio_write_fd_block(req->fd);
			_fd_writeDone(req->fd);
			_ioreq_dealloc(req);
		}
	}else {
		//no idle request on disk, despite removing from idle queue.. this shouldn't happen
		_q_insert(idle_q, (void *) req, key);
	}
}
コード例 #2
0
ファイル: ioreq.c プロジェクト: rit-sos/SOS
int _ioreq_enqueue(Drive *d, Fd *fd, Uint8 rd, Iostate state){
	Status status;
	Key key;
	Iorequest *req;

	if( (status = _q_remove( free_req_q, (void **) &req ))!= SUCCESS ) {
		_kpanic( "_ioreq_enqueue", "No free requests. Status: %s", status );
	}

	key.v =(void *) d;

	req->d=d;
	req->fd=fd;
	req->read=rd;
	req->st=state;

	if (state == WAIT_ON_IDLE){
		status = _q_insert( idle_q,(void *) req, key);
	}else if (state == WAIT_ON_DATA){
		status = _q_insert( data_q,(void *) req, key);
	}else{
		//drop invalid request
		status=FAILURE;
	}

	if( status != SUCCESS ) {
		_kpanic( "_ioreq_enqueue", "IO queue insertion status %s", status );
	}

	return 1;
}
コード例 #3
0
ファイル: ioreq.c プロジェクト: rit-sos/SOS
void _ioreq_dealloc(Iorequest *req){
	Key key;
	Status status;
	key.v = req->d;

	status = _q_insert(free_req_q, (void *) req,key);
	if( status != SUCCESS ) {
		_kpanic( "_ioreq_init", "IO free queue insertion status %s", status );
	}
}
コード例 #4
0
ファイル: scheduler.c プロジェクト: rit-sos/SOS
Status _sched( Pcb *pcb ) {
	Prio p;
	Key key;

	if( pcb == NULL ) {
		return( BAD_PARAM );
	}

	// Insert into one of the N ready queues
	// according to the priority of the process

	p = pcb->priority;
	if( p >= N_READYQ ) {
		return( BAD_PRIO );
	}

	key.u = pcb->pid;
	pcb->state = READY;
	return( _q_insert( _ready[p], (void *) pcb, key ) );

}
コード例 #5
0
ファイル: system.c プロジェクト: HostClub/HostOS
void _zombify( pcb_t *pcb ) {
	pcb_t *parent;
	status_t stat;
	pid_t pid;
	key_t key;
	info_t *info;

	// sanity check

	if( pcb == NULL ) {
		_kpanic( "_zombify", "null pcb", 0 );
	}

	// Locate the parent of this process

	parent = _pcb_find( pcb->ppid );

	if( parent == NULL ) {
		c_printf( "** zombify(): pid %d ppid %d\n",
			  pcb->pid, pcb->ppid );
		_kpanic( "_zombify", "no process parent", 0 );
	}

	//
	// Found the parent.  If it's waiting for this process,
	// wake it up, give it this process' status, and clean up.
	//

	if( parent->state == WAITING ) {

		// get the address of the info structure from the
		// parent, and pull out the desired PID

		info = (info_t *) ARG(parent->context,1);
		pid = info->pid;

		// if the parent was waiting for any of its children
		// or was waiting for us specifically, give it our
		// information and terminate this process.
		//
		// if the parent was waiting for another child,
		// turn this process into a zombie.

		if( pid == 0 || pid == _current->pid ) {

			// pull the parent off the waiting queue

			key.u = parent->pid;
			stat = _q_remove_by_key(&_waiting,(void **)&parent,key);
			if( stat != E_SUCCESS ) {
				_kpanic( "_zombify", "wait remove status %s",
					 stat );
			}

			// return our PID and our termination status
			// to the parent

			info->pid = _current->pid;
			info->status = ARG(_current->context,1);

			// clean up this process

			stat = _stack_free( pcb->stack );
			if( stat != E_SUCCESS ) {
				_kpanic( "_zombify", "stack free status %s",
					 stat );
			}

			stat = _pcb_free( pcb );
			if( stat != E_SUCCESS ) {
				_kpanic( "_zombify", "pcb free status %s",
					 stat );
			}

			// schedule the parent; give it a quick dispatch

			_schedule( parent, PRIO_MAXIMUM );

			return;
		}

	}

	//
	// Our parent either wasn't waiting, or was waiting for someone
	// else.  Put this process on the zombie queue until our parent
	// wants us.
	//

	key.u = _current->pid;
	_current->state = ZOMBIE;

	stat = _q_insert( &_zombie, (void *)_current, key );
	if( stat != E_SUCCESS ) {
		_kpanic( "_zombify", "zombie insert status %s", stat );
	}

}
コード例 #6
0
ファイル: system.c プロジェクト: agargiulo/DOSS
void _zombify( pcb_t *pcb ) {
	estatus_t *esptr;
	pid_t *pidptr;
	pid_t ppid;
	pcb_t *parent, *p2;
	int i;
	key_t key;
	status_t stat;
	
	// mark the process as no longer runnable

	pcb->state = ZOMBIE;

	// find the parent

	ppid = pcb->ppid;
	for( i = 0; i < N_PCBS; ++i ) {
		if( _pcbs[i].pid == ppid && _pcbs[i].state != FREE ) {
			parent = &_pcbs[i];
			break;
		}
	}
	
	/*
	** If we didn't find a parent, or if the parent was
	** already unrunnable (zombied, killed), reparent this
	** process to the init process
	*/

	if( i >= N_PCBS || _pcbs[i].state >= FIRST_DEAD_STATE ) {
		ppid = pcb->ppid = PID_INIT;
		parent = _init_pcb;
	}

	/*
	** At this point, parent points to the parent's PCB, and ppid
	** contains the parent's PID.
	**
	** If the parent is on the wait() queue, we'll awaken it and give
	** it this child's information.
	**
	** Otherwise, we need to put this child on the zombie queue.
	*/

	if( parent->state == WAITING ) {

		// look for the parent on the wait queue

		key.u = ppid;
		stat = _q_remove_specific( &_waiting, (void **) &p2, key );
		if( stat != SUCCESS ) {
			_kpanic( "_zombify", "parent wait remove status %s",
				 stat );
		}

		// verify that we found the same process

		if( p2 != parent ) {
			_pcb_dump( "*** p2:     ", p2 );
			_pcb_dump( "*** parent: ", parent );
			_kpanic( "_zombify", "parent wait deque wrong",
				 FAILURE );
		}

		// OK, we have the right one.

		// Start by decrementing its "remaining children"
		// counter if it isn't the init process

		if( ppid != PID_INIT ) {
			parent->children -= 1;
		}
		
		// return the child's information to it.

		RET(parent) = U_SUCCESS;

		pidptr = (pid_t *) ARG(parent)[1];
		*pidptr = pcb->pid;

		esptr = (estatus_t *) ARG(parent)[2];
		*esptr = ARG(pcb)[1];
		
		// schedule the parent (who returns from wait())

		_schedule( parent );
		
		// clean up the child process
		_pcb_cleanup( pcb );

	} else {

		// place this child on the zombie queue, ordered by PID

		key.u = pcb->pid;
		pcb->status = ARG(pcb)[1];

		stat = _q_insert( &_zombie, (void *)pcb, key );
		if( stat != SUCCESS ) {
			_kpanic( "_zombify", "zombie insert status %s",
				 stat );
		}

	}
	
}