示例#1
0
int syscall_sem_destroy(usr_sem_t* handle)
{
  int i;
  interrupt_status_t intr_status;

  intr_status = _interrupt_disable();
  spinlock_acquire(&usr_semaphore_table_slock);

  /* Look through the user semaphore table for
   * a usr_sem_t address matching the handle */
  for(i = 0; i < MAX_USR_SEMAPHORES; i++) {
    if(&usr_semaphore_table[i] == handle) {
      /* Invalidate the kernel semaphore and set the entry
       * in the userland semaphore table to empty */
      semaphore_destroy(handle->sem);
      usr_semaphore_table[i].sem = NULL;
      spinlock_release(&usr_semaphore_table_slock);
      _interrupt_set_state(intr_status);
      return 0;
    }
  }
  // If no match is found, return an error
  spinlock_release(&usr_semaphore_table_slock);
  _interrupt_set_state(intr_status);
  return 1;
}
示例#2
0
void process_finish(int retval) {
    interrupt_status_t intr_status;
    thread_table_t *thr = thread_get_current_thread_entry();
    process_id_t pid = process_get_current_process();
    
    int i;
    // remove parent references in other processes
    for (i = 0; i < PROCESS_MAX_PROCESSES; ++i) {
        intr_status = _interrupt_disable();
        spinlock_acquire(&process_table_slock);
        if (process_table[i].parent_id == pid)
            process_table[i].parent_id = -1;
        spinlock_release(&process_table_slock);
        _interrupt_set_state(intr_status);
    }
    
    intr_status = _interrupt_disable();
    spinlock_acquire(&process_table_slock);
    
    process_table[pid].retval = retval;
    process_table[pid].state = PROCESS_ZOMBIE;
    
    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    
    // clean up virtual memory
    vm_destroy_pagetable(thr->pagetable);
    thr->pagetable = NULL;
    
    thread_finish();
}
示例#3
0
文件: process.c 项目: jsfr/OSM-Buenos
/**
 *
 * Terminate the current process (maybe).  If the current process has
 * more than one running thread, only terminate the current thread.
 * The process is only completely terminated (as per process_join
 * wakeup and page table deallocation) when the final thread calls
 * process_finish().
 *
 * @param The return value of the process.  This is only used when the
 * final thread exits.
 *
 */
void process_finish(int retval)
{
    interrupt_status_t intr_status;
    thread_table_t *thread = thread_get_current_thread_entry();
    process_id_t pid = thread->process_id;

    if (retval < 0) {
        /* Not permitted! */
        retval = 0;
    }

    intr_status = _interrupt_disable();
    spinlock_acquire(&process_table_slock);

    /* Mark the stack as free so new threads can reuse it. */
    process_free_stack(thread);

    if (--process_table[pid].threads == 0) {
        /* We are the last thread - kill process! */
        vm_destroy_pagetable(thread->pagetable);

        finish_given_process(pid, retval);
    }

    thread->pagetable = NULL;

    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    thread_finish();
}
示例#4
0
文件: tty.c 项目: DIKU-EDU/kudos
/**
 * Reads atmost len bytes from tty-device pointed by
 * gcd to buffer buf.
 *
 * @param gcd Pointer to the tty-device.
 * @param buf Character buffer to be read into.
 * @param len Maximum number of bytes to be read.
 *
 * @return Number of succesfully read characters.
 */
static int tty_read(gcd_t *gcd, void *buf, int len) {
  interrupt_status_t intr_status;
  volatile tty_real_device_t *tty_rd
    = (tty_real_device_t *)gcd->device->real_device;
  int i;

  intr_status = _interrupt_disable();
  spinlock_acquire(tty_rd->slock);

  while (tty_rd->read_count == 0) {
    /* buffer is empty, so wait it to be filled */
    sleepq_add((void *)tty_rd->read_buf);
    spinlock_release(tty_rd->slock);
    thread_switch();
    spinlock_acquire(tty_rd->slock);
  }


  /* Data is read to internal buffer by interrupt driver. Number of
     chars read is stored to i. */
  i = 0;
  while (tty_rd->read_count > 0 && i < len) {
    ((char *)buf)[i++] = tty_rd->read_buf[tty_rd->read_head];
    tty_rd->read_head = (tty_rd->read_head + 1) % TTY_BUF_SIZE;
    tty_rd->read_count--;
  }

  spinlock_release(tty_rd->slock);
  _interrupt_set_state(intr_status);

  return i;
}
示例#5
0
/* Wait for the given process to terminate, return its return value,
   and mark the process-table entry as free */
int process_join(process_id_t pid){
  kprintf("Starten af process join pid = %d\n",pid);
  //Check if PID is valid
  if ((pid >= 0) && (pid < PROCESS_MAX_PROCESSES)) {
    interrupt_status_t intr_status;
    uint32_t retval;

    intr_status = _interrupt_disable();
    spinlock_acquire(&process_table_slock);

    /* Wait for the child process to exit and become a zombie. */
    while (process_table[pid].state != STATE_ZOMBIE) {
      /* Move to sleep queue and switch to another thread. */
      sleepq_add(&process_table[pid]);
      spinlock_release(&process_table_slock);
      thread_switch();
      spinlock_acquire(&process_table_slock);
    }

    /* Get the return value and prepare its slot for a future process. */
    retval = process_table[pid].retval;
    process_table[pid].state = STATE_FREE;

      //Release the respurce spinlock
    spinlock_release(&process_table_slock);
    //Restores the interrupt mask
    _interrupt_set_state(intr_status);

    return retval;
  }
  kprintf("Fejl i process join pid < 0 %d\n",pid);
  return -1;
}
示例#6
0
文件: process.c 项目: cfrost/buenos
int process_join(process_id_t pid) {
    int retval;
    interrupt_status_t intr_status;

    /* Only join with legal pids */
    if (pid < 0 || pid >= PROCESS_MAX_PROCESSES ||
            process_table[pid].parent != process_get_current_process())
        return PROCESS_ILLEGAL_JOIN;

    intr_status = _interrupt_disable();
    spinlock_acquire(&process_table_slock);

    /* The thread could be zombie even though it wakes us (maybe). */
    while (process_table[pid].state != PROCESS_ZOMBIE) {
        sleepq_add(&process_table[pid]);
        spinlock_release(&process_table_slock);
        thread_switch();
        spinlock_acquire(&process_table_slock);
    }

    retval = process_table[pid].retval;
    process_reset(pid);

    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    return retval;
}
示例#7
0
文件: process.c 项目: Eckankar/OSM-G
/**
 * Obtains and initializes a free process table slot.
 */
process_id_t process_obtain_slot(const char *executable) {
    interrupt_status_t intr_status;
    process_id_t pid = -1;

    // Ensure that we're the only ones touching the process table.
    intr_status = _interrupt_disable();
    spinlock_acquire(&process_table_slock);

    // Find a free process slot.
    int i;
	for(i = 0; i < MAX_PROCESSES; i++) {
		if(process_table[i].state == PROCESS_SLOT_AVAILABLE) {
			pid = i;
            break;
        }
	}

	// No free process slots.
	KERNEL_ASSERT(pid != -1);

	process_table[pid].state = PROCESS_RUNNING;
	stringcopy(process_table[pid].name, executable, MAX_NAME_LENGTH);
    process_table[pid].threads = 1;
    process_table[pid].stack_end = (USERLAND_STACK_TOP & PAGE_SIZE_MASK) -
                                        (CONFIG_USERLAND_STACK_SIZE-1)*PAGE_SIZE;
    process_table[pid].bot_free_stack = 0;

	// Free our locks.
    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);

    return pid;
}
示例#8
0
文件: lock_cond.c 项目: Jkirstejn/OSM
/*
 * Lock the given lock
 * uses waiting queues
 */
void lock_acquire(lock_t *lock) {

	interrupt_status_t intr_status;
	intr_status = _interrupt_disable();

	spinlock_acquire(&lock->spinlock);		// Acquire spinlock
	
	/* Check if lock is locked already */
	while (lock->state == LOCK_LOCKED) {
	
		/* Add thread to sleep queue and switch thread */
		sleepq_add(lock);
		
		spinlock_release(&lock->spinlock);	// Release spinlock
		
		thread_switch();
		spinlock_acquire(&lock->spinlock);	// Acquire spinlock
	}
	
	/* Lock open. Acquire it! */
	lock->state = LOCK_LOCKED;

	spinlock_release(&lock->spinlock);	// Release spinlock
	
	_interrupt_set_state(intr_status);
}
示例#9
0
semaphore_t *semaphore_create(int value)
{
  interrupt_status_t intr_status;
  static int next = 0;
  int i;
  int sem_id;
  
  KERNEL_ASSERT(value >= 0);
  
  intr_status = _interrupt_disable();
  spinlock_acquire(&semaphore_table_slock);
  
  /* Find free semaphore from semaphore table */
  for(i = 0; i < CONFIG_MAX_SEMAPHORES; i++) {
    sem_id = next;
    next = (next + 1) % CONFIG_MAX_SEMAPHORES;
    if (semaphore_table[sem_id].creator == -1) {
      semaphore_table[sem_id].creator = thread_get_current_thread();
      break;
    }
  }
  
  spinlock_release(&semaphore_table_slock);
  _interrupt_set_state(intr_status);
  
  if (i == CONFIG_MAX_SEMAPHORES) {
    /* semaphore table does not have any free semaphores, creation fails */
    return NULL;
  }
  
  semaphore_table[sem_id].value = value;
  spinlock_reset(&semaphore_table[sem_id].slock);
  
  return &semaphore_table[sem_id];
}
示例#10
0
文件: process.c 项目: Tayacan/OSM
process_id_t process_spawn(const char* executable)
{
  TID_t thread;
  interrupt_status_t intr_status;
  process_id_t my_pid = process_get_current_process();
  process_id_t pid = alloc_process_id(PROCESS_RUNNING);

  if (pid < 0) { /* Process table full */
    return -1;
  }
  stringcopy(process_table[pid].executable, executable, PROCESS_NAME_MAX);
  process_table[pid].retval = 0;
  process_table[pid].first_zombie = -1;
  process_table[pid].prev_zombie = -1;
  process_table[pid].next_zombie = -1;
  process_table[pid].parent = my_pid;
  process_table[pid].children = 0;

  intr_status = _interrupt_disable();
  spinlock_acquire(&process_table_slock);

  if (my_pid >= 0) {
    process_table[my_pid].children++;
  }

  spinlock_release(&process_table_slock);
  _interrupt_set_state(intr_status);

  thread = thread_create((void (*)(uint32_t))(&process_start), (uint32_t)pid);
  thread_run(thread);
  return pid;
}
示例#11
0
文件: thread.c 项目: Amr116/Buenos
/** 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);
}
示例#12
0
void condition_wait(cond_t *cond, lock_t *condition_lock)
{
    interrupt_status_t intr_status = _interrupt_disable();
    sleepq_add(cond); // tilføj til q
    _interrupt_set_state(intr_status);
    lock_release(condition_lock); // giv slip på låsen
    thread_switch(); // skift tråd
}
示例#13
0
文件: thread.c 项目: DIKU-EDU/kudos
/** 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);
}
示例#14
0
文件: process.c 项目: Tayacan/OSM
int process_join(process_id_t pid)
{
  process_id_t my_pid;
  uint32_t retval;
  interrupt_status_t intr_status;

  my_pid = process_get_current_process();
  if (pid < 0
      || pid >= PROCESS_MAX_PROCESSES
      || process_table[pid].parent != my_pid) {
    return -1;
  }

  intr_status = _interrupt_disable();
  spinlock_acquire(&process_table_slock);

  /* Loop until the process we are joining is a zombie. */
  while (process_table[pid].state != PROCESS_ZOMBIE) {
    sleepq_add(&process_table[pid]);
    spinlock_release(&process_table_slock);
    thread_switch();
    spinlock_acquire(&process_table_slock);
  }
  retval = process_table[pid].retval;

  /* Let children see it is gone. */
  process_table[pid].retval = -1;
  /* Make sure we can't join it again. */
  process_table[pid].parent = -1;

  if (process_table[pid].children == 0) {

    process_table[my_pid].children--;

    /* Remove the zombie child from our list of zombie children. */
    if (process_table[my_pid].first_zombie == pid) {
      process_id_t next = process_table[pid].next_zombie;
      process_table[my_pid].first_zombie = next;
      if (next >= 0) {
        process_table[next].prev_zombie = -1;
      }
    } else {
      process_id_t prev = process_table[pid].prev_zombie;
      process_id_t next = process_table[pid].next_zombie;
      process_table[prev].next_zombie = next;
      if (next >= 0) {
        process_table[next].prev_zombie = prev;
      }
    }

    process_reset(pid);

  }

  spinlock_release(&process_table_slock);
  _interrupt_set_state(intr_status);
  return retval;
}
示例#15
0
文件: usr_sem.c 项目: kazyka/OSM
usr_sem_t* usr_sem_open(const char* name, int value) {

  interrupt_status_t intr_status;
  intr_status = _interrupt_disable();

  spinlock_acquire(&sem_table_slock);

  if (value >= 0) {
    for (int i = 0; i < MAX_SEMAPHORES; i++) {
      if (usr_sem_table[i].name != NULL) {
        if (!stringcmp(usr_sem_table[i].name, name)) {
          spinlock_release(&sem_table_slock);
          _interrupt_set_state(intr_status);
          return NULL;
        }
      }
    }

    for (int j = 0; j < MAX_SEMAPHORES; j++) {
      if (usr_sem_table[j].name == NULL) {
        stringcopy(usr_sem_table[j].name, name, 8);
        usr_sem_table[j].value = value;
        spinlock_release(&sem_table_slock);
        return &usr_sem_table[j];
      }
    }

    spinlock_release(&sem_table_slock);
    _interrupt_set_state(intr_status);
    return NULL;
  }
  else {
    for (int k = 0; k < MAX_SEMAPHORES; k++) {
      if (stringcmp(usr_sem_table[k].name, name)) {

        spinlock_release(&sem_table_slock);
        return &usr_sem_table[k]; // return handle already in use
      }
    }
    spinlock_release(&sem_table_slock);
    _interrupt_set_state(intr_status);
    return NULL;
  }
}
示例#16
0
文件: process.c 项目: PtxDK/OSM
void* syscall_memlimit(void* new_end){
  uint32_t phys_page;
  interrupt_status_t intr_status;
  
  intr_status = _interrupt_disable();
  spinlock_acquire(&process_table_slock);
  
  process_control_block_t *curr_proc = process_get_current_process_entry();
  // checks if the new_end is NULL
  if (new_end == NULL){
    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    return (void*)curr_proc->heap_end;
  }
  // checks if we are trying to shrink the memory, if so we error
  // and return NULL
  if ((uint32_t)new_end < curr_proc->heap_end){
    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    return NULL;
  }
  // loop where we alloc the physical and the virtual memoery, we also check
  // if we have enough physical memory.
  for (uint32_t i = (curr_proc->heap_end / PAGE_SIZE +1);
       i <= ((uint32_t)new_end / PAGE_SIZE);i++){
    // we allocate some physical memory.
    phys_page = physmem_allocblock();
    //check if we got enough physical memory, if we do not we error
    if (phys_page == 0){
      spinlock_release(&process_table_slock);
      _interrupt_set_state(intr_status);
      return NULL;
    }
    // maps the virtual memory
    vm_map(thread_get_current_thread_entry()->pagetable,
           phys_page, i * PAGE_SIZE, 1);
  }
  // if nothing fails we at last set heap_end to  new_end
  curr_proc->heap_end = (uint32_t)new_end;
  
  spinlock_release(&process_table_slock);
  _interrupt_set_state(intr_status);
  return new_end;
}
示例#17
0
/* Stop the current process and the kernel thread in which it runs
   Argument: return value */
void process_exit(int retval){
  process_id_t pid;
  thread_table_t * thr;

  kprintf("starten af exit. reval: %d \n",retval);
  if (retval < 0){
    return;
  }

  // gets the process id
  pid = process_get_current_process();

  thr = thread_get_current_thread_entry();

  //spinlock
  spinlock_acquire(&process_table_slock);

  //Disbale interrupt
  _interrupt_set_state(_interrupt_disable());

  // set the process state to ZOMBIE
  process_table[pid].state = STATE_ZOMBIE;

  // Set the process retval to given retval  
  process_table[pid].retval = retval;

  //cleanup
  vm_destroy_pagetable(thr->pagetable);
  thr->pagetable = NULL;

  /* Wake process */
  sleepq_wake_all(&process_table[pid]);

  /* Unlock the process table */
  spinlock_release(&process_table_slock);
  
   //enable interrupts
  _interrupt_set_state(_interrupt_disable());

  kprintf("slutningen af exit :O \n");

  thread_finish();
}
示例#18
0
/**
 * Submits a request to the request queue. Request is inserted in the
 * queue by disk scheduler. 
 *
 * If request is synchronous (request->sem == NULL) call will block
 * and wait until the request is handled. Appropriate return value is
 * returned.
 *
 * If request is asynchronous (request->sem != NULL) call will return
 * immediately. 1 will be returned as retrun value.
 *
 * @param gbd Pointer to the gbd-device that will hadle request
 *
 * @param request Pointer to the request to be handled.
 *
 * @return 1 if success, 0 otherwise.
 */
static int disk_submit_request(gbd_t *gbd, gbd_request_t *request) 
{ 
    int sem_null; 
    interrupt_status_t intr_status; 
    disk_real_device_t *real_dev = gbd->device->real_device;

    request->internal = NULL;
    request->next     = NULL;
    request->return_value = -1;

    sem_null = (request->sem == NULL);
    if(sem_null) {
        /* Semaphore is null so this is synchronous request.
           Create a new semaphore with value 0. This will cause
           this function to block until the interrupt handler has 
           handled the request.
         */
        request->sem = semaphore_create(0);
        if(request->sem == NULL)
            return 0;   /* failure */
    }

    intr_status = _interrupt_disable();
    spinlock_acquire(&real_dev->slock);

    disksched_schedule(&real_dev->request_queue, request);

    if(real_dev->request_served == NULL) {
        /* Driver is idle so new request under work */
        disk_next_request(gbd);
    }

    spinlock_release(&real_dev->slock);
    _interrupt_set_state(intr_status);

    if(sem_null) {
        /* Synchronous call. Wait here until the interrupt handler has
           handled the request. After this semaphore created earlier
           in this function is no longer needed. */
        semaphore_P(request->sem);
        semaphore_destroy(request->sem);
        request->sem = NULL;

        /* Request is handled. Check the retrun value. */
        if(request->return_value == 0) 
            return 1;
        else
            return 0;
     
    } else {
        /* Asynchronous call. Assume success, because request is not yet
           handled. */
        return 1;
    }
}
示例#19
0
文件: process.c 项目: jsfr/OSM-Buenos
int process_fork(void (*func)(int), int arg)
{
    TID_t tid;
    thread_table_t *thread = thread_get_current_thread_entry();
    process_id_t pid = thread->process_id;
    interrupt_status_t intr_status;
    thread_params_t params;
    params.done = 0;
    params.func = func;
    params.arg = arg;
    params.pid = pid;
    params.pagetable = thread->pagetable;

    intr_status = _interrupt_disable();
    spinlock_acquire(&process_table_slock);

    tid = thread_create((void (*)(uint32_t))(setup_thread), (uint32_t)&params);

    if (tid < 0) {
        spinlock_release(&process_table_slock);
        _interrupt_set_state(intr_status);
        return -1;
    }

    process_table[pid].threads++;

    for(int i = 0 ; i < MAX_OPEN_FILES ; i++) {
        process_table[pid].open_files[i] = -1;
    }

    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    
    thread_run(tid);

    /* params will be dellocated when we return, so don't until the
       new thread is ready. */
    while (!params.done);

    return tid;
}
示例#20
0
文件: process.c 项目: Eckankar/OSM-G
void setup_thread(thread_params_t *params)
{
    context_t user_context;
    uint32_t phys_page;
    int i;
    interrupt_status_t intr_status;
    thread_table_t *thread= thread_get_current_thread_entry();

    /* Copy thread parameters. */
    int arg = params->arg;
    void (*func)(int) = params->func;
    process_id_t pid = thread->process_id = params->pid;
    thread->pagetable = params->pagetable;
    params->done = 1; /* OK, we don't need params any more. */

    intr_status = _interrupt_disable();
    spinlock_acquire(&process_table_slock);

    /* Set up userspace environment. */
    memoryset(&user_context, 0, sizeof(user_context));

    user_context.cpu_regs[MIPS_REGISTER_A0] = arg;
    user_context.pc = (uint32_t)func;

    /* Allocate thread stack */
    if (process_table[pid].bot_free_stack != 0) {
        /* Reuse old thread stack. */
        user_context.cpu_regs[MIPS_REGISTER_SP] =
            process_table[pid].bot_free_stack
            + CONFIG_USERLAND_STACK_SIZE*PAGE_SIZE
            - 4; /* Space for the thread argument */
        process_table[pid].bot_free_stack =
            *(uint32_t*)process_table[pid].bot_free_stack;
    } else {
        /* Allocate physical pages (frames) for the stack. */
        for (i = 0; i < CONFIG_USERLAND_STACK_SIZE; i++) {
            phys_page = pagepool_get_phys_page();
            KERNEL_ASSERT(phys_page != 0);
            vm_map(thread->pagetable, phys_page,
                    process_table[pid].stack_end - (i+1)*PAGE_SIZE, 1);
        }
        user_context.cpu_regs[MIPS_REGISTER_SP] =
            process_table[pid].stack_end-4; /* Space for the thread argument */
        process_table[pid].stack_end -= PAGE_SIZE*CONFIG_USERLAND_STACK_SIZE;
    }

    tlb_fill(thread->pagetable);

    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);

    thread_goto_userland(&user_context);
}
示例#21
0
void lock_release( lock_t *lock ) {
    interrupt_status_t intr_status;
    
    intr_status = _interrupt_disable();
    spinlock_acquire(&lock->slock);

    lock->locked = LOCK_UNLOCKED;
    sleepq_wake(lock);
    
    spinlock_release(&lock->slock);
    _interrupt_set_state(intr_status);
}
示例#22
0
文件: lock_cond.c 项目: bjornua/OSM
void lock_release(lock_t *lock){

    interrupt_status_t intr_status;
    intr_status = _interrupt_disable();
    spinlock_acquire(&(lock->spinlock));

    /* We unlock the lock and wake the next thread in the queue */
    lock->locked = 0;
    sleepq_wake(lock);

    spinlock_release(&(lock->spinlock));
    _interrupt_set_state(intr_status);
}
示例#23
0
文件: lock_cond.c 项目: bjornua/OSM
int lock_reset(lock_t *lock){

    interrupt_status_t intr_status;
    intr_status = _interrupt_disable();
    spinlock_release(&(lock->spinlock));

    lock->locked = 0;

    _interrupt_set_state(intr_status);
    spinlock_acquire(&(lock->spinlock));

    return 0;
}
示例#24
0
文件: thread.c 项目: Amr116/Buenos
thread_table_t *thread_get_current_thread_entry(void)
{
    TID_t t;
    interrupt_status_t intr_status;
      
    intr_status = _interrupt_disable();

    t = scheduler_current_thread[_interrupt_getcpu()];

    _interrupt_set_state(intr_status);

    return &thread_table[t];
}
示例#25
0
文件: lock_cond.c 项目: Jkirstejn/OSM
/*
 * Wait for a condition
 * Sleeps threads and waits for a signal from the given condition
 */
void condition_wait(cond_t *cond, lock_t *condition_lock) {

	interrupt_status_t intr_status;
	intr_status = _interrupt_disable();
	
	sleepq_add(cond);				// Wait for a signal from cond
	lock_release(condition_lock);	// Release the condition lock
	
	_interrupt_set_state(intr_status);
	thread_switch();				// Sleep thread
	
	lock_acquire(condition_lock);
}
示例#26
0
文件: xprintf.c 项目: ttsoftware/OSM
/* corresponding to vprintf(3) */
int kvprintf(const char *fmt, va_list ap) {
    int written;
    interrupt_status_t intr_state;

    intr_state = _interrupt_disable();
    spinlock_acquire(&kprintf_slock);

    written = vxnprintf((char*)0, 0x7fffffff, fmt, ap, FLAG_TTY);

    spinlock_release(&kprintf_slock);
    _interrupt_set_state(intr_state);

    return written;
}
示例#27
0
文件: tty.c 项目: DIKU-EDU/kudos
/**
 * Writes len bytes from buffer buf to tty-device
 * pointed by gcd. Implements write from the gbd interface.
 *
 * @param gcd Pointer to the tty-device.
 * @param buf Buffer to be written from.
 * @param len number of bytes to be written.
 *
 * @return Number of succesfully writeten characters.
 */
static int tty_write(gcd_t *gcd, const void *buf, int len) {
  interrupt_status_t intr_status;
  volatile tty_io_area_t *iobase = (tty_io_area_t *)gcd->device->io_address;
  volatile tty_real_device_t *tty_rd
    = (tty_real_device_t *)gcd->device->real_device;
  int i;

  intr_status = _interrupt_disable();
  spinlock_acquire(tty_rd->slock);

  i = 0;
  while (i < len) {
    while (tty_rd->write_count > 0) {
      /* buffer contains data, so wait until empty. */
      sleepq_add((void *)tty_rd->write_buf);
      spinlock_release(tty_rd->slock);
      thread_switch();
      spinlock_acquire(tty_rd->slock);
    }

    /* Fill internal buffer. */
    while (tty_rd->write_count < TTY_BUF_SIZE  && i < len) {
      int index;
      index = (tty_rd->write_head + tty_rd->write_count) % TTY_BUF_SIZE;
      tty_rd->write_buf[index] = ((char *)buf)[i++];
      tty_rd->write_count++;
    }

    /* If device is not currently busy, write one charater to
       cause interrupt. Head and count are adjusted not to write
       first character twice. Rest of the buffer is written by
       interrupt handler.

       If the device is busy, interrupt will appear by itself and
       the whole buffer will be written by interrupt handler.
    */
    if (!TTY_STATUS_WBUSY(iobase->status)) {
      iobase->data = tty_rd->write_buf[tty_rd->write_head];
      tty_rd->write_head = (tty_rd->write_head + 1) % TTY_BUF_SIZE;
      tty_rd->write_count--;
    }

  }

  spinlock_release(tty_rd->slock);
  _interrupt_set_state(intr_status);

  return i;
}
示例#28
0
void scheduler_add_ready(TID_t t)
{
    interrupt_status_t intr_status;
    
    intr_status = _interrupt_disable();

    spinlock_acquire(&thread_table_slock);

    scheduler_add_to_ready_list(t);
    thread_table[t].state = THREAD_READY;

    spinlock_release(&thread_table_slock);

    _interrupt_set_state(intr_status);
}
示例#29
0
文件: usr_sem.c 项目: kazyka/OSM
int usr_sem_vacate(usr_sem_t* sem) {
  interrupt_status_t intr_status;
  intr_status = _interrupt_disable();

  spinlock_acquire(&(sem->sem_slock));

  sem->value++;
  if (sem->value <= 0) {
    sleepq_wake(&(sem->value));
  }

  spinlock_release(&(sem->sem_slock));
  _interrupt_set_state(intr_status);
  return 0;
}
示例#30
0
文件: lock_cond.c 项目: Jkirstejn/OSM
/*
 * Reset condition
 * Used when creating a condition.
 * Assumes that space for the structure has been allocated
 */
int condition_reset(cond_t *cond) {

	interrupt_status_t intr_status;
	intr_status = _interrupt_disable();
	/* Assume error */
	int rtn = -1;
	
	/* Check if the condition points to some allocated space */
	if (cond != NULL) {
		cond->c = '\0';
		rtn = 0;
	}
	_interrupt_set_state(intr_status);
	return rtn;
}