extern void trapMemory(ExceptionStackFrame *exceptionStackFrame)
{
	TracePrintf(512, "trapMemory: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n",
	      exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr,
	      exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,
	      exceptionStackFrame->regs);

	if( exceptionStackFrame -> addr > current -> stack_brk )
	{
		 TracePrintf(0, "Trap Memory Error: addr: %d is large than stack_brk: %d\n", exceptionStackFrame -> addr, current -> stack_brk);
		 //Exit;
	}

	if( exceptionStackFrame -> addr < UP_TO_PAGE(current -> heap_brk) + PAGESIZE )
	{
		 TracePrintf(0, "Trap Memory Error: addr: %d is smaller than heap_brk: %d\n", exceptionStackFrame -> addr, current -> heap_brk);
		 //Exit;
	}

	long userTablePTE;	
	TracePrintf(510, "Moving user stack down to address: %d (%d)\n", exceptionStackFrame -> addr, (long)exceptionStackFrame -> addr >> PAGESHIFT);
	for (userTablePTE = (DOWN_TO_PAGE(exceptionStackFrame -> addr)); userTablePTE < (DOWN_TO_PAGE(current -> stack_brk)); userTablePTE += PAGESIZE)
	{
		unsigned int i = ((userTablePTE) >> PAGESHIFT) % PAGE_TABLE_LEN;
		UserPageTable[i].valid = 1;
		UserPageTable[i].uprot = PROT_NONE;
		UserPageTable[i].kprot = PROT_READ | PROT_WRITE;
		/* Need to change the pfn here */
		UserPageTable[i].pfn = allocatePhysicalPage();
		TracePrintf(250, "Allocate physical pages for user process: PID(%d), VPN(%d), PFN(%d).\n", current -> PID, i, UserPageTable[i].pfn);
	}
}
Esempio n. 2
0
void DoDelay(UserContext *context) {
    TracePrintf(1, "in DoDelay\n");
    current_process->clock_count = context->regs[0];
    TracePrintf(1, "Delay: %d\n", context->regs[0]);
    DelayAdd(current_process);
    LoadNextProc(context, BLOCK);
}
Esempio n. 3
0
void LoadNextProc(UserContext *context, int block) {
    DelayPop();
    if (!queueIsEmpty(ready_queue)) {
        if (current_process)  {
            current_process->user_context = *context;
            if (block == NO_BLOCK) {
                queuePush(ready_queue, current_process);
            }
        }

        PCB *next = queuePop(ready_queue);
        TracePrintf(1, "LoadNextProc: Next Process Id: %d\n", next->id);
        if(next->id == 2) 
            TracePrintf(3, "LoadNextProc: PCB has %p child\n", next->parent->children->head);
        WriteRegister(REG_PTBR1, (unsigned int) &(next->cow.pageTable)); 
        WriteRegister(REG_TLB_FLUSH, TLB_FLUSH_1);


        KernelContextSwitch(MyKCS, current_process, next);
        TracePrintf(1, "LoadNextProc: Got past MyKCS\n");
        *context = current_process->user_context;

        TracePrintf(3, "LoadNextProc: current user context pc is %p\n", context->pc);
    }
}
Esempio n. 4
0
/* This function make perfect mapping from kernel virtual memory phyical memory 
 */
void init_kernel_page_table() {
    kernel_page_table = (pte_t*) malloc(sizeof(pte_t) * GET_PAGE_NUMBER(VMEM_0_SIZE));
    
    // For text segment mapping
    TracePrintf(0, "Text Start=%p, End=%p\n", kernel_memory.text_low, kernel_memory.data_low);
    write_kernel_pte(kernel_memory.text_low, kernel_memory.data_low
            , _VALID, PROT_READ | PROT_EXEC);
    
    // For data segment mapping
    TracePrintf(0, "Data Start=%p, End=%p\n", kernel_memory.data_low, kernel_memory.brk_low);
    write_kernel_pte(kernel_memory.data_low, kernel_memory.brk_low
            , _VALID, PROT_READ | PROT_WRITE);
    
    // For stack segment mapping, noted that stack space is reserved even if it is not used
    TracePrintf(0, "Stack Start=%p, End=%p\n", KERNEL_STACK_BASE, KERNEL_STACK_LIMIT);
    write_kernel_pte(KERNEL_STACK_BASE, KERNEL_STACK_LIMIT
            , _VALID, PROT_READ | PROT_WRITE);
    
    int i;
    // Add free pages between heap and stack
    int start_pfn = GET_PAGE_NUMBER(UP_TO_PAGE(kernel_memory.brk_high));
    int end_pfn = GET_PAGE_NUMBER(DOWN_TO_PAGE(KERNEL_STACK_BASE));
    for(i = start_pfn; i < end_pfn; i++) {
        add_tail_available_frame(i);
    }
    // Add free pages above kernel space
    start_pfn = GET_PAGE_NUMBER(UP_TO_PAGE(VMEM_0_LIMIT));
    end_pfn = GET_PAGE_NUMBER(DOWN_TO_PAGE(PMEM_BASE)) + PAGE_SIZE;
    for(i = start_pfn; i < end_pfn; i++) {
        add_tail_available_frame(i);
    }
}
Esempio n. 5
0
void DoLockInit(UserContext *context) {
    
    if (BufferCheck(context->regs[0], INT_LENGTH) == ERROR || BufferWriteCheck(context->regs[0], INT_LENGTH) == ERROR) {
	TracePrintf(1, "DoLockInit: Pointer given not valid. Returning Error\n");
	context->regs[0] = ERROR;
	return;
    }

    Lock *lock = malloc(sizeof(Lock));
    if (lock == NULL) {
        TracePrintf(2, "CreateLock, malloc error\n");
        context->regs[0] = ERROR;
        return;
    }

    lock->waiting = queueNew();
    if (lock->waiting == NULL) {
        TracePrintf(2, "CreateLock: malloc error\n");
        context->regs[0] = ERROR;
        return;
    }
    lock->cvars = 0;

    int lock_id = lock_count * NUM_RESOURCE_TYPES + LOCK;
    lock_count++;
    lock->id = lock_id;
    *((int *) context->regs[0]) = lock_id;

    queuePush(locks, lock);
    context->regs[0] = SUCCESS;
}
extern int KernelBrk(void *addr, struct PCBNode *pcb)
{
	TracePrintf(256, "Brk: addr(%d)\n", addr);

	//check if the addr is illegal
	if(addr < MEM_INVALID_SIZE)
	{
		  TracePrintf(0, "Error in KernelBrk: Trying to set the brk below MEM_INVALID_SIZE.\n");
		  //Exit the program.
	}

	if(addr > DOWN_TO_PAGE(pcb -> stack_brk) - PAGESIZE)
	{
		  TracePrintf(0, "Error in KernelBrk: Trying to set the brk inside or above the red zone.\n");
	}

    unsigned int userTablePTE;
    //Only allocate for entire pages??
    unsigned int gap = (UP_TO_PAGE(addr)-UP_TO_PAGE(pcb -> heap_brk));
    if(gap>0)
	{
		TracePrintf(250, "Moving user brk up to address: %d (%d)\n", addr, (long)addr >> PAGESHIFT);
		for (userTablePTE = (UP_TO_PAGE(pcb -> heap_brk)); userTablePTE < (UP_TO_PAGE(addr)); userTablePTE += PAGESIZE)
		{
			unsigned int i = ((userTablePTE) >> PAGESHIFT) % PAGE_TABLE_LEN;
			UserPageTable[i].valid = 1;
			UserPageTable[i].uprot = PROT_NONE;
			UserPageTable[i].kprot = PROT_READ | PROT_WRITE;
			/* Need to change the pfn here */
			UserPageTable[i].pfn = allocatePhysicalPage();
			TracePrintf(250, "Allocate physical pages for user process: PID(%d), VPN(%d), PFN(%d).\n", pcb -> PID, i, UserPageTable[i].pfn);
		}
	}
extern int KernelFork(void)
{
	TracePrintf(256, "Fork\n");
	struct PCBNode cur_active = *active_process;
	struct PCBNode* newproc = malloc(sizeof(struct PCBNode));
	if(newproc == NULL) return ERROR;
	newproc = (struct PCBNode *)malloc(sizeof(struct PCBNode));
	newproc -> PID = nextPID(); 
	//will need to change this thing later
	newproc -> pageTable = malloc(PAGE_TABLE_LEN * sizeof(struct pte));
	newproc -> status = READY;
	newproc -> blockedReason = 0;
	newproc -> numTicksRemainForDelay = 0;
	newproc -> parent = NULL;
	newproc -> child = NULL;
	newproc -> prevSibling = NULL;
	newproc -> nextSibling = NULL;
	TracePrintf(100, "Fork enter context switch\n");
	ContextSwitch(forkSwitchFunc, &(cur_active.ctxp), &cur_active, newproc);
	TracePrintf(100, "Fork left context switch\n");
	if(cur_active.PID == active_process->PID){
	  //return from parent
	  return newproc->PID;
	}else{
	  //this is returning from child, which means we should maintain the child queue
	  return 0;
	}
	return 0;
}
Esempio n. 8
0
void DoWait(UserContext *context) {
    if (BufferCheck(context->regs[0], INT_LENGTH) == ERROR || BufferWriteCheck(context->regs[0], INT_LENGTH) == ERROR) {
        TracePrintf(1, "DoWait: Pointer given not valid. Returning Error\n");
        context->regs[0] = ERROR;
        return;
    }


	if (queueIsEmpty(current_process->children) && queueIsEmpty(current_process->deadChildren)) {
		TracePrintf(2, "DoWait: PCB %d Has no children. Returning Error.\n", current_process->id);
		TracePrintf(2, "DoWait: Children queue count: %d, deadChildren count: %d\n", current_process->children->length, current_process->deadChildren->length);
		context->regs[0] = ERROR;
	} else {
		if (queueIsEmpty(current_process->deadChildren)) {
			current_process->status = WAITING;
			queuePush(wait_queue, current_process);
			LoadNextProc(context, BLOCK);
		}

        ZCB *child = queuePop(current_process->deadChildren);
        queueRemove(process_queue, child);
        *((int *)context->regs[0]) = child->status;
        context->regs[0] = child->id;
    }
}
int main(int argc, char *argv[]) { 
  
  TracePrintf(1, "\t===>Start: tty.c.c\n");
  char write_msg[] = "Hello World!";
  int size = sizeof(write_msg);
  
  int rc;
  rc = Fork();
  if (rc == 0) {
    Pause();
    Pause();
    Pause();
    Pause();
    TtyWrite(1, write_msg, size);
    TracePrintf(1, "\t===>tty.c: Just wrote to terminal 1.\n");
    return 0;
  } else {
    char read_msg[10];
    size = sizeof(read_msg);
    TtyRead(2, read_msg, size);
    TracePrintf(1, "\t===>tty.c: Just read from terminal 2: %s.\n", read_msg);
  }
  
  TracePrintf(1, "\t===>End: tty.c.c\n");
  
  return 0;
} 
Esempio n. 10
0
void DoIdle(void) {
	while(1) {
		TracePrintf(0, "********************************************************************************\n");
		TracePrintf(0, "***************************  DoIlde is running!  *******************************\n");
		TracePrintf(0, "********************************************************************************\n");
		Pause();
	}
}
Esempio n. 11
0
int
queueIsEmpty(Queue *queue) {
    TracePrintf(4, "queueIsEmpty: queue->head = %p, queue->length = %d\n", queue->head, queue->length);
    if (queue->head == NULL) {
        TracePrintf(4, "queueIsEmpty: queue is empty\n");
    }
    return (queue->head == NULL);
}
Esempio n. 12
0
// Print error message and kill proc
void TrapIllegal(UserContext *user_context) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> TrapIllegal(%p)\n", user_context);
    char *err_str = calloc(TERMINAL_MAX_LINE, sizeof(char));
    sprintf(err_str, "TRAP_ILLEGAL exception for proc %d\n", current_proc->pid);
    KernelTtyWriteInternal(0, err_str, strnlen(err_str, TERMINAL_MAX_LINE), user_context);
    free(err_str);
    KernelExit(ERROR, user_context);
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< TrapIllegal(%p)\n", user_context);
}
Esempio n. 13
0
// Get a copy of the currently running Kernel Context and save it in the current pcb
KernelContext *SaveCurrentKernelContext(KernelContext *kernel_context, void *current_pcb,
        void *next_pcb) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> SaveCurrentKernelContext()\n");

    ((PCB*) current_pcb)->kernel_context = *kernel_context;

    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< SaveCurrentKernelContext()\n");
    return kernel_context;
}
Esempio n. 14
0
void TrapTtyRecieve(UserContext *user_context) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> TrapTtyRecieve(%p)\n", user_context);
    int tty_id = user_context->code;
    
    // Find the proper terminal struct
    Tty term = ttys[tty_id];
    if (ListEmpty(term.waiting_to_receive)) { 
        // no waiting procs, so create line buffer and
        // add to list
        LineBuffer *lb = calloc(1, sizeof(LineBuffer));
        lb->buffer = calloc(TERMINAL_MAX_LINE, sizeof(char));
        lb->length = TtyReceive(tty_id, lb->buffer, TERMINAL_MAX_LINE);
        ListEnqueue(term.line_buffers, lb, 0);
    } else { 
        // at least one proc waiting
        // create heap in kernel to use
        char *input = calloc(TERMINAL_MAX_LINE, sizeof(char));
        char *input_ptr = input; // point how far into the buffer we've read
        int input_length = TtyReceive(tty_id, input, TERMINAL_MAX_LINE);
        int input_remaining = input_length;

        // Continue so long as procs are waiting and there is unconsumed input
        while (!ListEmpty(term.waiting_to_receive) && input_remaining > 0) {
            PCB *waiting_proc = (PCB *) ListDequeue(term.waiting_to_receive);
            assert(waiting_proc->tty_receive_buffer);

            // put proc back into ready queue
            ListAppend(ready_queue, waiting_proc, waiting_proc->pid);

            if (input_remaining <= waiting_proc->tty_receive_len) {
                // Consuming all the input
                memcpy(waiting_proc->tty_receive_buffer, input_ptr, input_remaining);
                waiting_proc->tty_receive_len = input_remaining;
                input_remaining = 0;
            } else {
                // Only consuming some of the input
                memcpy(waiting_proc->tty_receive_buffer, input_ptr, waiting_proc->tty_receive_len);
                input_remaining -= waiting_proc->tty_receive_len;
                input_ptr += waiting_proc->tty_receive_len;
            }
        }

        // Check if there is still input left after all the procs have been filled
        if (input_remaining > 0) {
            // Create new line buffer and store
            char *remaining_buff = calloc(input_remaining, sizeof(char));
            memcpy(remaining_buff, input_ptr, input_remaining);
            LineBuffer *lb = calloc(1, sizeof(LineBuffer));
            lb->buffer = remaining_buff;
            lb->length = input_remaining;
            ListEnqueue(term.line_buffers, lb, 0);
        }

        free(input);
    }
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< TrapTtyRecieve(%p)\n", user_context);
}
Esempio n. 15
0
// Print message and kill
void TrapMath(UserContext *user_context) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> TrapMath(%p)\n", user_context);
    TracePrintf(TRACE_LEVEL_NON_TERMINAL_PROBLEM, "Killing proc on trap math \n");
    char *err_str = calloc(TERMINAL_MAX_LINE, sizeof(char));
    sprintf(err_str, "TRAP_MATH exception for proc %d\n", current_proc->pid);
    KernelTtyWriteInternal(0, err_str, strnlen(err_str, TERMINAL_MAX_LINE), user_context);
    free(err_str);
    KernelExit(ERROR, user_context);
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< TrapMath(%p)\n", user_context);
}
Esempio n. 16
0
void DoExec(UserContext *context) {
    TracePrintf(5, "DoExec\n");
    current_process->user_context = *context;
    TracePrintf(5, "DoExec: LoadProgram\n");
    int rc = LoadProgram(context->regs[0], context->regs[1], current_process);
    TracePrintf(5, "DoExec: finished LoadProgram\n");
    if (rc != SUCCESS) {
        current_process->user_context.regs[0] = ERROR;
    }
    *context = current_process->user_context;
    TracePrintf(5, "Finished DoExec\n");
}
Esempio n. 17
0
void DoPS(UserContext *context) {
    TracePrintf(3, "DoPS: In DoPS\n");
    for (List *process = process_queue->head; process; process = process->next) {
        if (((ZCB *) process->data)->status == DEAD) {
            TracePrintf(1, "PID: %d. DEAD\n", ((ZCB *) process->data)->id);
        } else {
            TracePrintf(1, "PID: %d.\n", ((PCB *) process->data)->id);
        }
    }
    context->regs[0] = SUCCESS;
    return;
}
Esempio n. 18
0
int main(int argc, char **argv) {
  int i;
  TracePrintf(-1, "In process %d\n", GetPid());
  printf("In process %d\n", GetPid());
  
  TracePrintf(-1, "%d arguments passed in\n", argc);
  printf("%d arguments passed in\n", argc);
  for (i = 0; i < argc; i++) {
    TracePrintf(-1, "\targ %d is %s\n", i, argv[i]);
    printf("\targ %d is %s\n", i, argv[i]);
  }
  return 0;
}
Esempio n. 19
0
// Context switch to the next process in the ready queue.
// The next process's context will be loaded into the param user_context.
// NOTE: place the current proc into the correct queue before calling
// (e.g., ready queue, clock blocked queue)
void SwitchToNextProc(UserContext *user_context) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> SwitchToNextProc()\n");

    // Get the proc at the front of the queue
    PCB *next_proc = ListDequeue(ready_queue);
    if (next_proc) {
        SwitchToProc(next_proc, user_context);
    } else { // No procs waiting, so just switch to the idle proc
        TracePrintf(TRACE_LEVEL_DETAIL_INFO, "No waiting procs, idling\n");
        SwitchToProc(idle_proc, user_context);
    }

    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< SwitchToNextProc()\n");
}
int main(int argc, char *argv[]) {
  TracePrintf(1, "\t===>pipe.c\n");
  int pipe_id;
  int rc;

  if (PipeInit(&pipe_id) != 0)
    TracePrintf(1, "Failed to initialize pipe\n");
  else
    TracePrintf(1, "Pipe Initialized. ID = %d\n", pipe_id);

  rc = Fork();
  if (rc == 0) {
    char *to_write = (char *)malloc(5 * sizeof(char));
    to_write[0] = 'a';
    to_write[1] = 'b';
    to_write[2] = 'c';
    to_write[3] = 'd';
    to_write[4] = 'e';

    char *second_write = (char *)malloc(2 * sizeof(char));
    second_write[0] = 'e';
    second_write[1] = 'f';

    int written;


    Pause();
    TracePrintf(1, "\tCHILD: about to write to the lock\n");
    written = PipeWrite(pipe_id, to_write, 4);
    TracePrintf(1, "\tCHILD: wrote %d characters to the lock\n", written);

    Pause();
    TracePrintf(1, "\tCHILD: pausing once\n");

    Pause();
    written = PipeWrite(pipe_id, second_write, 2);
    TracePrintf(1, "\tCHILD: wrote to the pipe again (%d chars)\n", written);

    Pause();
    Exit(0);
  } else {
    char *to_read = (char *)malloc(6 * sizeof(char));
    int read;
    Pause();
    Pause();
    TracePrintf(1, "\tPARENT: reading 6 chars from the pipe (before it's ready\n");
    read = PipeRead(pipe_id, to_read, 6);
    TracePrintf(1, "\tPARENT: read %d chars from the pipe. Results: %s\n", read, to_read);

    Pause();
    Exit(0);
  }

  return 0;
}
Esempio n. 21
0
// Method pased to ListMap on clock tick
// decrements the number of ticks remaining for each proc that is waiting from Delay
void DecrementTicksRemaining(void *_proc) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> DecrementTicksRemaining(%p)\n", _proc);
    PCB *proc = (PCB *) _proc;
    --proc->clock_ticks_until_ready;
    if (proc->clock_ticks_until_ready <= 0) {
        TracePrintf(TRACE_LEVEL_FUNCTION_INFO, 
            ">>> DecrementTicksRemaining: proc %p done waiting!\n",
             _proc);

        ListRemoveById(clock_block_procs, proc->pid);
        ListAppend(ready_queue, proc, proc->pid);
    }
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< DecrementTicksRemaining()\n");
}
Esempio n. 22
0
void TrapTtyTransmit(UserContext *user_context) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> TrapTtyTransmit(%p)\n", user_context);
    int tty_id = user_context->code;
    Tty term = ttys[tty_id];
    assert(!ListEmpty(term.waiting_to_transmit));

    // Get the currently transmitting proc (always at the front of the list)
    PCB *waiting_proc = (PCB *) ListPeak(term.waiting_to_transmit);
    if (waiting_proc->tty_transmit_len > TERMINAL_MAX_LINE) { 
        // not completely transmitted, so handle pointer stuff and leave in
        // front of the queue
        waiting_proc->tty_transmit_pointer += TERMINAL_MAX_LINE;
        waiting_proc->tty_transmit_len -= TERMINAL_MAX_LINE;

        // transmit min(MAX_LINE, len)
        if (TERMINAL_MAX_LINE > waiting_proc->tty_transmit_len) {
            TtyTransmit(tty_id, waiting_proc->tty_transmit_pointer,
                waiting_proc->tty_transmit_len);
        } else {
            TtyTransmit(tty_id, waiting_proc->tty_transmit_pointer,
                TERMINAL_MAX_LINE);
        }

        return;
    }

    // transmission complete
    // since done, take off transmitting list
    ListRemoveById(term.waiting_to_transmit, waiting_proc->pid);
    ListAppend(ready_queue, waiting_proc, waiting_proc->pid);
    free(waiting_proc->tty_transmit_buffer);

    if (ListEmpty(term.waiting_to_transmit)) {
        return; // no other procs waiting on this term
    }

    // Get the next proc waiting to submit
    PCB *next_to_transmit = (PCB *) ListPeak(term.waiting_to_transmit);
    // transmit min(MAX_LINE, len)
    if (TERMINAL_MAX_LINE > next_to_transmit->tty_transmit_len) {
        TtyTransmit(tty_id, next_to_transmit->tty_transmit_pointer,
            next_to_transmit->tty_transmit_len);
    } else {
        TtyTransmit(tty_id, next_to_transmit->tty_transmit_pointer,
            TERMINAL_MAX_LINE);
    }

    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< TrapTtyTransmit(%p)\n", user_context);
}
Esempio n. 23
0
int LockRelease(Lock *lock) {
    if (lock == NULL) {
        TracePrintf(2, "LockRelease: Lock not found.\n");
        return ERROR;
    } else if (lock->owner != current_process) {
        TracePrintf(2, "LockRelease: Current process does not hold lock it is trying to release.\n");
        return ERROR;
    } else {
        lock->owner = queuePop(lock->waiting);
        if (lock->owner) {
            queuePush(ready_queue, lock->owner);
        } 
        return SUCCESS;
    }
}
Esempio n. 24
0
void main(void) {
    int delay = 4;
    int delays[512];
    int delays2[1024];
    //int delays3[1024 * 2];
    //int delays4[1024 * 4];
    //int delays5[1024 * 8];
    while(1) {
        TracePrintf(1, "GJJ is coding like a boss.\n");
//       Delay(delay);
        Pause();
    }
    TracePrintf(1, "GJJ leaving the init proc\n");
    return;
}
Esempio n. 25
0
void TrapClock(UserContext *user_context) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> TrapClock(%p)\n", user_context);
    // Use Map interface to decrement the ticks remaining for each proc
    ListMap(clock_block_procs, &DecrementTicksRemaining);

    // If the current proc is not the idle, place it in the ready queue
    if (current_proc->pid != IDLE_PID) {
        ListAppend(ready_queue, current_proc, current_proc->pid);
    }

    // and switch to the next ready proc
    SwitchToNextProc(user_context);

    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< TrapClock(%p)\n", user_context);
}
extern void trapIllegal(ExceptionStackFrame *exceptionStackFrame)
{
  TracePrintf(512, "trapIllegal: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n",
	      exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr, 
	      exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,
	      exceptionStackFrame->regs);
  int code = exceptionStackFrame->code;
  char string[128];
  char* msg = string;
  
  if (code == ILL_BADSTK)
    msg = "Bad stack\n";
  else if (code == ILL_ILLOPC || code == ILL_ILLOPN || code == ILL_ILLADR)
    msg = "Illegal instruction\n";
  else if (code == ILL_PRVOPC || code == ILL_PRVREG)
    msg = "Privileged instruction\n";
  else if (code == ILL_COPROC)
    msg = "Coprocessor error\n";
  else if (code == ILL_ILLTRP)
    msg = "Illegal software trap\n";
  else if (code == BUS_ADRALN + 20)
    printf(msg, "Invalid address alignment %p", exceptionStackFrame->addr);
  else if (code == SI_KERNEL)
    msg = "Linux kernel SIGILL\n";
  else if (code == SI_USER)
    msg = "Received SIGILL from user\n";
  else
    printf(msg, "Unknown code 0x%x", code);
  
  //KernelExit(ERROR);
  printf(msg);
}
Esempio n. 27
0
void writeBridgeToPipe() {
    int rc = PipeWrite(pipe_id, (void *) b, sizeof(Bridge));
    if (rc != sizeof(Bridge)) {
        TracePrintf(TRACE_LEVEL_TERMINAL_PROBLEM, "FAILED TO WRITE BRIDGE\n");
        Exit(-1);
    }
}
Esempio n. 28
0
void DoSpoon(UserContext *context) {
    // Get an available process id.                                                                                       
    int newPid = pidCount++;
    PCB *child = (PCB *)malloc(sizeof(PCB));

    // If for any reason we can't fork, return ERROR to calling process.                                                  
    if (!newPid || !child) {
        context->regs[0] = ERROR;
        return;
    }

    PCB_Init(child);
    child->id = newPid;
    child->parent = current_process;
    queuePush(child->parent->children, child);
    if (queueIsEmpty(child->parent->children))
        TracePrintf(3, "DoSpoon: parent queue empty.\n");


    child->status = RUNNING;

    // Return 0 to child and arm the child for execution.                                                                 
    child->user_context = *context;
    queuePush(ready_queue, child);
    queuePush(process_queue, child);
    KernelContextSwitch(SpoonKernel, current_process, child);

    // Return child's pid to parent and resume execution of the parent.                                                   
    if (current_process->id == newPid) {
        *context = current_process->user_context;
        context->regs[0] = 0;
    } else {
        context->regs[0] = newPid;
    }
}
int main(int argc, char *argv[]) {
    while (1) {
        TracePrintf(1, "Do Init Prog!\n");
        Pause();
    }
    return 0;
}
Esempio n. 30
0
void DoExit(UserContext *context) {
    if (1 == current_process->id) {
        TracePrintf(1, "Do Exit: init program exiting. Now calling halt.\n");
        Halt();
    }

    if (current_process->parent) {
        current_process->status = context->regs[0];
    }

    TracePrintf(2, "DoExit\n");

    KillProc(current_process);

    TracePrintf(2, "DoExit: Finished the murder\n");
    LoadNextProc(context, BLOCK);
}