Пример #1
0
/** Perform voluntary rescheduling. The current (=calling) thread will
 * voluntary end its time slice when this function is called. The
 * thread will remain in a ready state, and if there are no other
 * threads which are ready to run, the calling thread will resume its
 * execution immediately. This should NOT be used as a substitute for
 * sleeping.
 */
void thread_switch(void)
{
      interrupt_status_t intr_status;
      
      intr_status = _interrupt_enable();
      _interrupt_generate_sw0();
      _interrupt_set_state(intr_status);
}
Пример #2
0
/** Perform voluntary rescheduling. The current (=calling) thread will
 * voluntary end its time slice when this function is called. The
 * thread will remain in a ready state, and if there are no other
 * threads which are ready to run, the calling thread will resume its
 * execution immediately. This should NOT be used as a substitute for
 * sleeping.
 */
void thread_switch(void)
{
  interrupt_status_t intr_status;

  intr_status = _interrupt_enable();
  _interrupt_yield();
  _interrupt_set_state(intr_status);
}
Пример #3
0
int process_join(process_id_t pid) {
// kprintf("PROCESS JOIN ER STARTET\n");

 spinlock_t lock;
   if (!(process_table[pid].parent_id = process_get_current_process()))
     return PROCESS_ILLEGAL_JOIN;

//  kprintf("PROCESS JOIN ER LEGAL\n");
  // disable interrupts.
  _interrupt_disable();
//  kprintf("interrupts disabled\n"); 
  //acquire the resource spinlock
  spinlock_reset(&lock);
  spinlock_acquire(&lock);
//  kprintf("LOCK er ACQUIRED\n");
  //add to sleeq..
  process_table[process_get_current_process()].state = WAITING;
  while(!(process_table[pid].state == ZOMBIE)) {
   sleepq_add(&process_table[pid]);

  //release the resource spinlock.
   spinlock_release(&lock);
//  kprintf("TRÅD BLIVER SAT I SENG\n");

  //thread_switch()
   thread_switch();

  //Acquire the resource spinlock.
   spinlock_acquire(&lock);
  }

  //Do your duty with the resource (Frigøre processen, nu hvor den er færdig)
  process_table[pid].state = FREE;

  //release the resource spinlock
  spinlock_release(&lock);
  process_table[process_get_current_process()].state = RUNNING;
  //Restore the interrupt mask.
  _interrupt_enable();

//  kprintf("PROCESS_JOIN ER KOMMET IGENNEM\n");
  return process_table[process_get_current_process()].retval;
}
Пример #4
0
/** Perform suicide. The calling thread will kill itself by freeing
 * its memory and other resources and marking itself as dying. The
 * scheduler will free the thread table entry when it encounters dying
 * threads.
 */
void thread_finish(void)
{
    TID_t my_tid;

    my_tid = thread_get_current_thread();

    _interrupt_disable();

    /* Check that the page mappings have been cleared. */
    KERNEL_ASSERT(thread_table[my_tid].pagetable == NULL);

    spinlock_acquire(&thread_table_slock);
    thread_table[my_tid].state = THREAD_DYING;
    spinlock_release(&thread_table_slock);

    _interrupt_enable();
    _interrupt_generate_sw0();

    /* not possible without a stack? alternative in assembler? */
    KERNEL_PANIC("thread_finish(): thread was not destroyed");
}
Пример #5
0
void init(void)
{
    TID_t startup_thread;
    int numcpus;

    /* Initialize polling TTY driver for kprintf() usage. */
    polltty_init();

    kwrite("BUENOS is a University Educational Nutshell Operating System\n");
    kwrite("==========================================================\n");
    kwrite("\n");

    kwrite("Copyright (C) 2003-2006  Juha Aatrokoski, Timo Lilja,\n");
    kwrite("  Leena Salmela, Teemu Takanen, Aleksi Virtanen\n");
    kwrite("See the file COPYING for licensing details.\n");
    kwrite("\n");

    kwrite("Initializing memory allocation system\n");
    kmalloc_init();

    kwrite("Reading boot arguments\n");
    bootargs_init();

    /* Seed the random number generator. */
    if (bootargs_get("randomseed") == NULL) {
	_set_rand_seed(0);
    } else {
	int seed = atoi(bootargs_get("randomseed"));
	kprintf("Seeding pseudorandom number generator with %i\n", seed);
	_set_rand_seed(seed);
    }

    numcpus = cpustatus_count();
    kprintf("Detected %i CPUs\n", numcpus);
    KERNEL_ASSERT(numcpus <= CONFIG_MAX_CPUS);

    kwrite("Initializing interrupt handling\n");
    interrupt_init(numcpus);

    kwrite("Initializing threading system\n");
    thread_table_init();

    kwrite("Initializing user process system\n");
    process_init();

    kwrite("Initializing sleep queue\n");
    sleepq_init();

    kwrite("Initializing semaphores\n");
    semaphore_init();

    kwrite("Initializing device drivers\n");
    device_init();

    kprintf("Initializing virtual filesystem\n");
    vfs_init();

    kwrite("Initializing scheduler\n");
    scheduler_init();

    kwrite("Initializing virtual memory\n");
    vm_init();

    kprintf("Creating initialization thread\n");
    startup_thread = thread_create(&init_startup_thread, 0);
    thread_run(startup_thread);

    kprintf("Starting threading system and SMP\n");

    /* Let other CPUs run */
    kernel_bootstrap_finished = 1;
    
    _interrupt_clear_bootstrap();
    _interrupt_enable();

    /* Enter context switch, scheduler will be run automatically,
       since thread_switch() behaviour is identical to timer tick
       (thread timeslice is over). */
    thread_switch();

    /* We should never get here */
    KERNEL_PANIC("Threading system startup failed.");
}
Пример #6
0
/** Handles an exception (code != 0) that occured in user mode. Will
 * call appropiate handlers for the exception or panic if the
 * exception should not have occured or does not (yet) have a handler.
 * Interrupts are disabled by EXL when this function is called, and
 * must be so when this fucntion returns. Interrupts may be enabled
 * during execution of this function if needed.
 *
 * @param exception The exception code field from the CP0 Cause register
 */
void user_exception_handle(int exception)
{
    thread_table_t *my_entry;

    /* While interrupts are disabled here, they can be enabled when
       handling system calls and certain other exceptions if needed.
       For normal TLB exceptions it is not desirable that context is
       switched before TLB is filled. */
    _interrupt_disable();

    /* Clear EXL to make normal interrupt disable/enable work. */
    _interrupt_clear_EXL();

    /* Save usermode context to user_context for later reference in syscalls */
    my_entry= thread_get_current_thread_entry();
    my_entry->user_context = my_entry->context;

    switch(exception) {
    case EXCEPTION_TLBM:
        tlb_modified_exception();
        break;
    case EXCEPTION_TLBL:
        tlb_load_exception();
        break;
    case EXCEPTION_TLBS:
        tlb_store_exception();
        break;
    case EXCEPTION_ADDRL:
        KERNEL_PANIC("Address Error Load: not handled yet");
        break;
    case EXCEPTION_ADDRS:
        KERNEL_PANIC("Address Error Store: not handled yet");
        break;
    case EXCEPTION_BUSI:
        KERNEL_PANIC("Bus Error Instruction: not handled yet");
        break;
    case EXCEPTION_BUSD:
        KERNEL_PANIC("Bus Error Data: not handled yet");
        break;
    case EXCEPTION_SYSCALL:
        _interrupt_enable();
        syscall_handle(my_entry->user_context);
        _interrupt_disable();
        break;
    case EXCEPTION_BREAK:
        KERNEL_PANIC("Breakpoint: not handled yet");
        break;
    case EXCEPTION_RESVI:
        kprintf("Thread ID: %d\n", thread_get_current_thread());
        KERNEL_PANIC("Reserved instruction: not handled yet");
        break;
    case EXCEPTION_COPROC:
        KERNEL_PANIC("Coprocessor unusable: buggy assembler code?");
        break;
    case EXCEPTION_AOFLOW:
        KERNEL_PANIC("Arithmetic overflow: buggy assembler code?");
        break;
    case EXCEPTION_TRAP:
        KERNEL_PANIC("Trap: this just should not happen");
        break;
    default:
        KERNEL_PANIC("Unknown exception");
    }

    /* Interrupts are disabled by setting EXL after this point. */
    _interrupt_set_EXL();
    _interrupt_enable();

}
Пример #7
0
void init(void)
{
    TID_t startup_thread;
    int numcpus;

    /* Initialise Static Allocation */
    stalloc_init();

    /* Initialize polling TTY driver for kprintf() usage. */
    polltty_init();

    kwrite("Kudos is an educational operating system by the University of Copenhagen\n");
    kwrite("========================================================================\n");
    kwrite("Based on the Buenos operating system skeleton\n");
    kwrite("\n");

    kprintf("Copyright (C) 2003-2016  Juha Aatrokoski, Timo Lilja,\n");
    kprintf("  Leena Salmela, Teemu Takanen, Aleksi Virtanen, Philip Meulengracht,\n");
    kprintf("  Troels Henriksen, Annie Jane Pinder, Niels Gustav Westphal Serup,\n");
    kprintf("  Nicklas Warming Jacobsen, Oleksandr Shturmov.\n");
    kwrite("See the file COPYING for licensing details.\n");
    kwrite("\n");

    kwrite("Reading boot arguments\n");
    bootargs_init((void*)BOOT_ARGUMENT_AREA);

    /* Seed the random number generator. */
    if (bootargs_get("randomseed") == NULL) {
        _set_rand_seed(0);
    } else {
        int seed = atoi(bootargs_get("randomseed"));
        kprintf("Seeding pseudorandom number generator with %i\n", seed);
        _set_rand_seed(seed);
    }

    numcpus = cpustatus_count();
    kprintf("Detected %i CPUs\n", numcpus);
    KERNEL_ASSERT(numcpus <= CONFIG_MAX_CPUS);

    kwrite("Initializing interrupt handling\n");
    interrupt_init(numcpus);

    kwrite("Initializing threading system\n");
    thread_table_init();

    kwrite("Initializing sleep queue\n");
    sleepq_init();

    kwrite("Initializing semaphores\n");
    semaphore_init();

    kwrite("Initializing device drivers\n");
    device_init();

    kprintf("Initializing virtual filesystem\n");
    vfs_init();

    kwrite("Initializing scheduler\n");
    scheduler_init();

    kwrite("Initializing virtual memory\n");
    vm_init();

    kprintf("Creating initialization thread\n");
    startup_thread = thread_create(&init_startup_thread, 0);
    thread_run(startup_thread);

    kprintf("Starting threading system and SMP\n");

    /* Let other CPUs run */
    kernel_bootstrap_finished = 1;

    _interrupt_clear_bootstrap();
    _interrupt_enable();

    /* Enter context switch, scheduler will be run automatically,
       since thread_switch() behaviour is identical to timer tick
       (thread timeslice is over). */
    thread_switch();

    /* We should never get here */
    KERNEL_PANIC("Threading system startup failed.");
}