Beispiel #1
0
void _dispatch( void ) {
	int i;
	Status status;

	// select a process from the highest-priority
	// ready queue that is not empty

	for( i = 0; i < N_READYQ; ++i ) {

	   do {

		if( _q_empty(_ready[i]) ) {
			break;
		}

		// found one - make it the currently-running process
		status = _q_remove( _ready[i], (void **) &_current );
		if( status == SUCCESS ) {

			// check to see if it needs to be cleaned up
			if( _current->state == KILLED ) {
				// yes - deallocate it
				_cleanup( _current );
				// go back and re-check this queue
				continue;
			}

			_current->state = RUNNING;
			_current->quantum = STD_QUANTUM;
			return;
		} else {
			_kpanic( "_dispatch", "readyq deque status %s",
				 status );
		}

	   } while( 1 );

	}

	_kpanic( "_dispatch", "no non-empty readyq", EMPTY_QUEUE );

}
Beispiel #2
0
status_t _q_append( queue_t *queue, void *data, key_t key ) {
	qnode_t *qnode;
	status_t stat;

	// sanity check

	if( queue == NULL ) {
		// INCONSISTENCY
		_kpanic( "_q_append", "null queue", 0 );
	}

	// first, get a qnode structure

	stat = _qnode_alloc( &qnode );
	if( stat != E_SUCCESS ) {
		return( stat );
	}

	// fill in the necessary information

	qnode->key = key;
	qnode->data = data;

	// add the node to the end of the queue

	if( _q_empty(queue) ) {
		queue->head = qnode;
	} else {
		queue->tail->next = qnode;
	}

	qnode->next = NULL;
	qnode->prev = queue->tail;
	queue->tail = qnode;

	queue->length += 1;

	return( E_SUCCESS );

}
Beispiel #3
0
status_t _q_remove( queue_t *queue, void **data ) {
	qnode_t *qnode;

	// sanity check

	if( queue == NULL || data == NULL ) {
		return( E_BAD_PARAM );
	}

	// if no nodes in the queue, we're done

	if( _q_empty(queue) ) {
		return( E_EMPTY );
	}

	// remove the first node from the queue

	qnode = queue->head;
	queue->length -= 1;

	queue->head = qnode->next;

	if( queue->head == NULL ) {
		queue->tail = NULL;
	} else {
		queue->head->prev = NULL;
	}

	// return the data field to the caller

	*data = qnode->data;

	// propogate the qnode deallocation status

	return( _qnode_free( qnode ) );

}
Beispiel #4
0
status_t _q_insert( queue_t *queue, void *data, key_t key ) {
	qnode_t *qnode;
	qnode_t *curr;
	status_t stat;

	// sanity check

	if( queue == NULL ) {
		return( E_BAD_PARAM );
	}

	// allocate a queue node

	stat = _qnode_alloc( &qnode );
	if( stat != E_SUCCESS ) {
		return( stat );
	}

	// fill in the necessary information

	qnode->key = key;
	qnode->data = data;
	qnode->prev = NULL;
	qnode->next = NULL;

	// if the queue is empty, no need to find the "right" place

	if( _q_empty(queue) ) {
		queue->head = qnode;
		queue->tail = qnode;
		queue->length = 1;
		return( E_SUCCESS );
	}

	// no comparison routine means append

	if( queue->compare == NULL ) {
		queue->tail->next = qnode;
		qnode->prev = queue->tail;
		queue->tail = qnode;
		queue->length += 1;
		return( E_SUCCESS );
	}

	//
	// traverse the queue looking for the correct insertion point,
	// as indicated by the built-in comparison routine
	//

	curr = queue->head;
	while( curr != NULL && queue->compare(curr,qnode) <= 0 ) {
		curr = curr->next;
	}

	// add at the end of the queue

	if( curr == NULL ) {
		queue->tail->next = qnode;
		qnode->prev = queue->tail;
		queue->tail = qnode;
		queue->length += 1;
		return( E_SUCCESS );
	}

	// insert in the middle of the queue

	qnode->next = curr;
	if( curr->prev == NULL ) {
		queue->head = qnode;
	} else {
		curr->prev->next = qnode;
		qnode->prev = curr->prev;
	}
	curr->prev = qnode;

	queue->length += 1;

	return( E_SUCCESS );

}
Beispiel #5
0
status_t _q_remove_by_key( queue_t *queue, void **data, key_t key ) {
	qnode_t *qnode;
	status_t stat;

	// verify that our parameters are usable

	if( queue == NULL || data == NULL ) {
		return( E_BAD_PARAM );
	}

	// if the queue is empty, nothing to do

	if( _q_empty(queue) ) {
		return( E_EMPTY );
	}

	// if there is no specialized removal routine, do an ordinary remove

	if( queue->remove == NULL ) {
		return( _q_remove(queue,data) );
	}

	//
	// Traverse the queue, looking for the correct element.
	// Use the built-in removal routine to determine when
	// we have found the correct entry.
	//

	qnode = queue->head;
	while( qnode != NULL && !queue->remove(qnode->key,key) ) {
		qnode = qnode->next;
	}

	// did we find the one we wanted?

	if( qnode == NULL ) {
		return( E_NOT_FOUND );
	}

	// found the correct node - unlink it from the queue

	if( qnode->prev != NULL ) {
		qnode->prev->next = qnode->next;
	} else {
		queue->head = qnode->next;
	}

	if( qnode->next != NULL ) {
		qnode->next->prev = qnode->prev;
	} else {
		queue->tail = qnode->prev;
	}

	queue->length -= 1;

	// return the data from the node

	*data = qnode->data;

	// release the qnode
	//
	// INCONSISTENCY:  _q_remove() just propogates the status

	stat = _qnode_free( qnode );
	if( stat != E_SUCCESS ) {
		_kpanic( "_q_remove_by_key", "qnode free failed, %s", stat );
	}

	return( E_SUCCESS );

}
Beispiel #6
0
/**
 * Writes the given character to the focused process, if one exists. Otherwise
 * the character is discarded.
 * 
 * @param	c		The character to write
 */
void _ps2_write_to_active( char c ){

	// Grab focused process
	Pid active_p = get_active_pid();

	// Throw away the character if there is no focused process
	if( active_p == 0 ){
		return;
	}


	// Find the IO-request for this process
	int index = 0;
	while( index < TOTAL_IO_REQS ){
		if( requests[ index ]->pid == active_p )
			break;
		index ++;
	}
	if( index == TOTAL_IO_REQS )
		return; // The focused process does not want input
	
	// Write the character
	// Check if we need to return a special character, or write to buf
	//c_printf( "Index: %d    Size: %d\n", requests[ index ]->index, requests[ index ]->size);
	char *buf = requests[ index ]->buf;
	Uint8 flags = 0;
	//c_printf(" Writing Buf Addr: 0x%x\n", buf);
	Uint32 currentCr3 = _isr_vmem_getcr3();
	_vmeml2_change_page(requests[ index ]->pdt);
	//c_printf(" Writing Buf Addr: 0x%x 0x%x\n", buf, buf+sizeof(char));
	if( requests[ index ]->size == 0 ){
		buf[1] = c;
		if( shift_pressed )
			flags = flags | 4;
		if( alt_pressed )
			flags = flags | 2;
		if( ctrl_pressed )
			flags = flags | 1;
		buf[0] = (char) flags;
		Pcb *pcb = _ps2_remove_from_queue( index );
		_ps2_delete_request( index );
		_sched( pcb );
	}
	else{
		// We need to print the character for the user
        screen_info* si = get_screen_info( active_p );
        gl_putchar_s( c, si );

		// store the character
		int i = requests[ index ]->index;
		if( c != '\n'){
			buf[ i ] = c;
			requests[ index ]->index = i + 1;
		}
		
		// stop reading if full, or newline
		if( i == requests[ index ]->size || c == '\n' ){
			buf[ i ] = '\0';
			
			// pull from IO-blocking queue
			if( !_q_empty( _buf_block ) ){
				Pcb *pcb = _ps2_remove_from_queue( index );
				_sched( pcb );
			}
			else{
				// did someone forcefully remove it!?!
				c_printf( "keyboard, write active: buffered block queue is"
							" empty???\n" );
			}
			
			// Delete the process from our IO request array
			_ps2_delete_request( index );
		}
	}
	_vmeml2_change_page( currentCr3);
}