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 ); }
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 ); }
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 ) ); }
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 ); }
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 ); }
/** * 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); }