예제 #1
0
파일: sem.c 프로젝트: codeyangjun/ucore
static __noinline uint32_t __down(semaphore_t *sem, uint32_t wait_state)
{
	bool intr_flag;
	local_intr_save(intr_flag);
	if (sem->value > 0)
	{
		sem->value--;
		local_intr_restore(intr_flag);
		return 0;
	}
	wait_t __wait, *wait = &__wait;
	wait_current_set(&(sem->wait_queue), wait, wait_state);
	local_intr_restore(intr_flag);

	schedule();

	local_intr_save(intr_flag);
	wait_current_del(&(sem->wait_queue), wait);
	local_intr_restore(intr_flag);

	if (wait->wakeup_flags != wait_state)
	{
		return wait->wakeup_flags;
	}
	return 0;
}
예제 #2
0
파일: sem.c 프로젝트: TySag/project
    __attribute__ ((noinline)) __down(semaphore_t * sem, uint32_t wait_state,
				      timer_t * timer)
{
	assert(sem->valid);
	bool intr_flag;
	local_intr_save(intr_flag);
	if (sem->value > 0) {
		sem->value--;
		local_intr_restore(intr_flag);
		return 0;
	}
	wait_t __wait, *wait = &__wait;
	wait_current_set(&(sem->wait_queue), wait, wait_state);
	ipc_add_timer(timer);
	local_intr_restore(intr_flag);

	schedule();

	local_intr_save(intr_flag);
	ipc_del_timer(timer);
	wait_current_del(&(sem->wait_queue), wait);
	local_intr_restore(intr_flag);

	if (wait->wakeup_flags != wait_state) {
		return wait->wakeup_flags;
	}
	return 0;
}
예제 #3
0
static int
recv_event(int *pid_store, int *event_store, timer_t *timer) {
    bool intr_flag;
    local_intr_save(intr_flag);
    wait_queue_t *wait_queue = &(current->event_box.wait_queue);
    if (wait_queue_empty(wait_queue)) {
        current->state = PROC_SLEEPING;
        current->wait_state = WT_EVENT_RECV;
        ipc_add_timer(timer);
        local_intr_restore(intr_flag);

        schedule();

        local_intr_save(intr_flag);
        ipc_del_timer(timer);
    }

    int ret = -1;

    wait_t *wait;
    if ((wait = wait_queue_first(wait_queue)) != NULL) {
        struct proc_struct *proc = wait->proc;
        *pid_store = proc->pid, *event_store = proc->event_box.event, ret = 0;
        wakeup_wait(wait_queue, wait, WT_EVENT_SEND, 1);
    }
    local_intr_restore(intr_flag);
    return ret;
}
예제 #4
0
파일: sched.c 프로젝트: haozhun/ucore_plus
int
try_to_wakeup(struct proc_struct *proc) {
  assert(proc->state != PROC_ZOMBIE);
  int ret;
  bool intr_flag;
  local_intr_save(intr_flag);
  {
    if (proc->state != PROC_RUNNABLE) {
      proc->state = PROC_RUNNABLE;
      proc->wait_state = 0;
      if (proc != current) {
        sched_class_enqueue(proc);
      }
      ret = 1;
    }
    else {
      ret = 0;
    }
    struct proc_struct *next = proc;
    while ( (next = next_thread(next)) != proc ) {
      if ( next->state == PROC_SLEEPING && next->wait_state == WT_SIGNAL ) {
        next->state = PROC_RUNNABLE;
        next->wait_state = 0;
        if ( next != current ) {
          sched_class_enqueue(next);
        }
      }
    }
  }
  local_intr_restore(intr_flag);
  return ret;
}
예제 #5
0
// serial only atm
void cons_putc(int c)
{
	/* An temporary version, just for debugging.*/
	//serial_putc(c);
	bool intr_flag;
        local_intr_save(intr_flag);
        {
		serial_putc(c);
	}
        local_intr_restore(intr_flag);
/*
	bool intr_flag;
	local_intr_save(intr_flag);
	{
#ifdef USE_UART
		serial_putc(c);
#endif
#ifdef HAS_SDS
		if (check_sds() && is_debugging())
			sds_poll_proc();
		sds_putc(0, c);
#endif
	}
	local_intr_restore(intr_flag);*/
}
예제 #6
0
/* *
 * cons_getc - return the next input character from console,
 * or 0 if none waiting.
 * */
int cons_getc(void)
{
	int c = 0;
	bool intr_flag;
	local_intr_save(intr_flag);
	{
		// poll for any pending input characters,
		// so that this function works even when interrupts are disabled
		// (e.g., when called from the kernel monitor).
#ifdef USE_UART
		serial_intr();
#endif
#ifdef HAS_SDS
		if (check_sds() && is_debugging())
			sds_poll_proc();
		sds_intr();
#endif
		//kbd_intr();

		// grab the next character from the input buffer.
		if (cons.rpos != cons.wpos) {
			c = cons.buf[cons.rpos++];
			if (cons.rpos == CONSBUFSIZE) {
				cons.rpos = 0;
			}
		}
	}
	local_intr_restore(intr_flag);
	return c;
}
예제 #7
0
파일: sched.c 프로젝트: FeibHwang/Hurlex-II
void schedule(void)
{
        struct task_struct *task_next = NULL;
        struct list_head *le = NULL, *last = NULL;

        bool intr_flag = false;
        local_intr_store(intr_flag);
        {
                current->need_resched = false;

                // 如果当前是内核调度线程在执行,就从任务链起始开始,否则从当前任务开始
                le = last = (current == glb_idle_task) ? &task_list : &(current->list);
                for (le = le->next; le != last; le = le->next) {
                        if (le != &task_list) {
                                task_next = le_to_task(le);
                                if (task_next->state == TASK_RUNNABLE) {
                                        break;
                                }
                        }
                }

                // 未找到可运行的任务
                if (!task_next || task_next->state != TASK_RUNNABLE) {
                        task_next = glb_idle_task;
                }

                // 时间片递增
                task_next->runs_time++;

                if (task_next != current) {
                        task_run(task_next);
                }
        }
        local_intr_restore(intr_flag);
}
예제 #8
0
파일: sched.c 프로젝트: xieyf13/POS2016
void
schedule(void) {
    bool intr_flag;
    struct proc_struct *next;
    local_intr_save(intr_flag);
    {
	cprintf("\n++++++ CURRENT PID = %d ++++++\n", current->pid);
        cprintf("++++++ IN SCHEDULE() ++++++\n");
        current->need_resched = 0;
        if (current->state == PROC_RUNNABLE) {
            cprintf("++++++ CURRENT PID = %d RUNNABLE, CALL ENQUEUE ++++++\n", current->pid);
            sched_class_enqueue(current);
        }
        if ((next = sched_class_pick_next()) != NULL) {
            cprintf("++++++ NEXT PID = %d TO RUN, CALL DEQUEUE ++++++\n", next->pid);
            sched_class_dequeue(next);
        }
        if (next == NULL) {
            next = idleproc;
        }
        next->runs ++;
        if (next != current) {
            proc_run(next);
        }
    }
    local_intr_restore(intr_flag);
}
예제 #9
0
파일: sched.c 프로젝트: codeyangjun/ucore
void schedule(void)
{
	bool intr_flag;
	struct proc_struct *next;
	local_intr_save(intr_flag);
	{
		current->need_resched = 0;
		if (current->state == PROC_RUNNABLE)
		{
			sched_class_enqueue(current);
		}
		if ((next = sched_class_pick_next()) != NULL)
		{
			sched_class_dequeue(next);
		}
		if (next == NULL)
		{
			next = idleproc;
		}
		next->runs++;
		if (next != current)
		{
			proc_run(next);
		}
	}
	local_intr_restore(intr_flag);
}
예제 #10
0
파일: sched.c 프로젝트: ryz1/OSryz
// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
void
run_timer_list(void) {
    bool intr_flag;
    local_intr_save(intr_flag);
    {
        list_entry_t *le = list_next(&timer_list);
        if (le != &timer_list) {
            timer_t *timer = le2timer(le, timer_link);
            assert(timer->expires != 0);
            timer->expires --;
            while (timer->expires == 0) {
                le = list_next(le);
                struct proc_struct *proc = timer->proc;
                if (proc->wait_state != 0) {
                    assert(proc->wait_state & WT_INTERRUPTED);
                }
                else {
                    warn("process %d's wait_state == 0.\n", proc->pid);
                }
                cprintf("process pid = %d wait finished.",proc->pid);
                wakeup_proc(proc);
                del_timer(timer);
                if (le == &timer_list) {
                    break;
                }
                timer = le2timer(le, timer_link);
            }
        }
        sched_class_proc_tick(current);
    }
    local_intr_restore(intr_flag);
}
예제 #11
0
파일: sched.c 프로젝트: lhh520/os-4-risc-v
void
schedule(void) {
    bool intr_flag;
    list_entry_t *le, *last;
    struct proc_struct *next = NULL;
    local_intr_save(intr_flag);
    {
        current->need_resched = 0;
        last = (current == idleproc) ? &proc_list : &(current->list_link);
        le = last;
        do {
            if ((le = list_next(le)) != &proc_list) {
                next = le2proc(le, list_link);
                if (next->state == PROC_RUNNABLE) {
                    break;
                }
            }
        } while (le != last);
        if (next == NULL || next->state != PROC_RUNNABLE) {
            next = idleproc;
        }
        next->runs ++;
        if (next != current) {
        	//proc_print(next);
        	cprintf("sche! proc %d, pc=%08x\n\n",next->pid,next->context.pc);
            //cprintf("sp=%08x\n\n",read_sp());
            proc_run(next);
        }
    }
    local_intr_restore(intr_flag);
}
예제 #12
0
파일: sched.c 프로젝트: ryz1/OSryz
void
schedule(void) {
    bool intr_flag;
    struct proc_struct *next;
    local_intr_save(intr_flag);
    {
        current->need_resched = 0;
        if (current->state == PROC_RUNNABLE) {
            cprintf("Timer finished for process pid = %d and push in the queue\n",current->pid);
            sched_class_enqueue(current);
        }
        if ((next = sched_class_pick_next()) != NULL) {
            cprintf("Picks process pid = %d to run and pop from the queue\n",next->pid);
            sched_class_dequeue(next);
        }
        if (next == NULL) {
            cprintf("No runnable process.\n");
            next = idleproc;
        }
        next->runs ++;
        if (next != current) {
            proc_run(next);
        }
    }
    local_intr_restore(intr_flag);
}
예제 #13
0
파일: sched.c 프로젝트: 151706061/ucore_lab
void
schedule(void) {
    bool intr_flag;
    list_entry_t *le, *last;
    struct proc_struct *next = NULL;
    local_intr_save(intr_flag);
    {
        current->need_resched = 0;
        last = (current == idleproc) ? &proc_list : &(current->list_link);
        le = last;
        do {
            if ((le = list_next(le)) != &proc_list) {
                next = le2proc(le, list_link);
                if (next->state == PROC_RUNNABLE) {
                    break;
                }
            }
        } while (le != last);
        if (next == NULL || next->state != PROC_RUNNABLE) {
            next = idleproc;
        }
        next->runs ++;
        if (next != current) {
            proc_run(next);
        }
    }
    local_intr_restore(intr_flag);
}
예제 #14
0
// try_free_pages - calculate pressure to estimate the number(pressure<<5) of needed page frames in ucore currently, 
//                - then call kswapd kernel thread.
bool
try_free_pages(size_t n) {
	struct proc_struct *current = pls_read(current);

    if (!swap_init_ok || kswapd == NULL) {
        return 0;
    }
	if (current == kswapd) {
        panic("kswapd call try_free_pages!!.\n");
    }
    if (n >= (1 << 7)) {
        return 0;
    }
    pressure += n;

    wait_t __wait, *wait = &__wait;

    bool intr_flag;
    local_intr_save(intr_flag);
    {
        wait_init(wait, current);
        current->state = PROC_SLEEPING;
        current->wait_state = WT_KSWAPD;
        wait_queue_add(&kswapd_done, wait);
        if (kswapd->wait_state == WT_TIMER) {
            wakeup_proc(kswapd);
        }
    }
    local_intr_restore(intr_flag);

    schedule();

    assert(!wait_in_queue(wait) && wait->wakeup_flags == WT_KSWAPD);
    return 1;
}
예제 #15
0
int __ucore_wakeup_by_pid(int pid)
{
	//kprintf("ucore_wakeup_by_pid %d\n", pid);
	struct proc_struct *proc = find_proc(pid);
	if (!proc)
		return -E_INVAL;
	bool flag;
	local_intr_save(flag);
	if (proc->state == PROC_ZOMBIE) {
		local_intr_restore(flag);
		return -E_INVAL;
	}
	if (proc->state == PROC_RUNNABLE)
		wakeup_proc(proc);
	local_intr_restore(flag);
	return 0;
}
예제 #16
0
파일: pmm.c 프로젝트: kobemiller/Hurlex-II
void free_pages(uint32_t addr, uint32_t n)
{
        uint32_t eflag;
        
        local_intr_store(eflag);
        pmm_manager->free_pages(addr, n);
        local_intr_restore(eflag);
}
예제 #17
0
/* cons_putc - print a single character @c to console devices */
void
cons_putc(int c) {
    bool intr_flag;
    local_intr_save(intr_flag);
    {
        serial_putc(c);
    }
    local_intr_restore(intr_flag);
}
예제 #18
0
static void
kswapd_wakeup_all(void) {
    bool intr_flag;
    local_intr_save(intr_flag);
    {
        wakeup_queue(&kswapd_done, WT_KSWAPD, 1);
    }
    local_intr_restore(intr_flag);
}
예제 #19
0
파일: pmm.c 프로젝트: lhh520/os-4-risc-v
//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory 
void
free_pages(struct Page *base, size_t n) {
    bool intr_flag;
    local_intr_save(intr_flag);
    {
        pmm_manager->free_pages(base, n);
    }
    local_intr_restore(intr_flag);
}
예제 #20
0
uint32_t todo_wait_interruptible(wait_queue_t* wait_queue, uint32_t wait_state)
{
    bool intr_flag;
    local_intr_save(intr_flag);
//    wait_t __wait, *wait = &__wait;
//    wait_current_set(&wait_queue, wait, wait_state);
    local_intr_restore(intr_flag);

    schedule();

    local_intr_save(intr_flag);
//    wait_current_del(&(sem->wait_queue), wait);
    local_intr_restore(intr_flag);

//    if (wait->wakeup_flags != wait_state) {
//        return wait->wakeup_flags;
//    }
    return 0;
}
예제 #21
0
void __ucore_wait_self()
{
	//kprintf("ucore_wait_self self=%d\n", current->pid);
	bool intr_flag;
	local_intr_save(intr_flag);
	current->state = PROC_SLEEPING;
	current->wait_state = WT_KERNEL_SIGNAL;
	local_intr_restore(intr_flag);
	schedule();
}
예제 #22
0
파일: sem.c 프로젝트: spinlock/ucore
bool
try_down(semaphore_t *sem) {
    bool intr_flag, ret = 0;
    local_intr_save(intr_flag);
    if (sem->value > 0) {
        sem->value --, ret = 1;
    }
    local_intr_restore(intr_flag);
    return ret;
}
예제 #23
0
파일: pmm.c 프로젝트: Aresthu/ucore_plus
/**
 * free_pages - call pmm->free_pages to free a continuing n*PAGESIZE memory
 * @param base the first page to be freed
 * @param n number of pages to be freed
 */
void free_pages(struct Page *base, size_t n)
{
	bool intr_flag;
	local_intr_save(intr_flag);
	{
		pmm_manager->free_pages(base, n);
	}
	local_intr_restore(intr_flag);
	pls_write(used_pages, pls_read(used_pages) - n);
}
예제 #24
0
//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory 
void
free_pages(struct Page *base, size_t n) {
    bool intr_flag;
    local_intr_save(intr_flag);
	spinlock_acquire(&pmm_lock);
    {
        pmm_manager->free_pages(base, n);
    }
	spinlock_release(&pmm_lock);
    local_intr_restore(intr_flag);
}
예제 #25
0
파일: pmm.c 프로젝트: lhh520/os-4-risc-v
//nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) 
//of current free memory
size_t
nr_free_pages(void) {
    size_t ret;
    bool intr_flag;
    local_intr_save(intr_flag);
    {
        ret = pmm_manager->nr_free_pages();
    }
    local_intr_restore(intr_flag);
    return ret;
}
예제 #26
0
// copy_mm - process "proc" duplicate OR share process "current"'s mm according clone_flags
//         - if clone_flags & CLONE_VM, then "share" ; else "duplicate"
static int
copy_mm(uint32_t clone_flags, struct proc_struct *proc) {
    struct mm_struct *mm, *oldmm = current->mm;

    /* current is a kernel thread */
    if (oldmm == NULL) {
        return 0;
    }
    if (clone_flags & CLONE_VM) {
        mm = oldmm;
        goto good_mm;
    }

    int ret = -E_NO_MEM;
    if ((mm = mm_create()) == NULL) {
        goto bad_mm;
    }
    if (setup_pgdir(mm) != 0) {
        goto bad_pgdir_cleanup_mm;
    }

    lock_mm(oldmm);
    {
        ret = dup_mmap(mm, oldmm);
    }
    unlock_mm(oldmm);

    if (ret != 0) {
        goto bad_dup_cleanup_mmap;
    }

good_mm:
    if (mm != oldmm) {
        mm->brk_start = oldmm->brk_start;
        mm->brk = oldmm->brk;
        bool intr_flag;
        local_intr_save(intr_flag);
        {
            list_add(&(proc_mm_list), &(mm->proc_mm_link));
        }
        local_intr_restore(intr_flag);
    }
    mm_count_inc(mm);
    proc->mm = mm;
	set_pgdir (proc, mm->pgdir);
    return 0;
bad_dup_cleanup_mmap:
    exit_mmap(mm);
    put_pgdir(mm);
bad_pgdir_cleanup_mm:
    mm_destroy(mm);
bad_mm:
    return ret;
}
예제 #27
0
파일: pmm.c 프로젝트: kobemiller/Hurlex-II
uint32_t alloc_pages(uint32_t n)
{
        uint32_t page;
        uint32_t eflag;
        
        local_intr_store(eflag);
        page = pmm_manager->alloc_pages(n);
        local_intr_restore(eflag);

        return page;
}
예제 #28
0
파일: sched.c 프로젝트: haozhun/ucore_plus
void
stop_proc(struct proc_struct *proc, uint32_t wait) {
  bool intr_flag;
  local_intr_save(intr_flag);
  proc->state = PROC_SLEEPING;
  proc->wait_state = wait;
  if ( !list_empty(&(proc->run_link)) ) {
    sched_class_dequeue(proc);
  }
  local_intr_restore(intr_flag);
}
예제 #29
0
// 屏幕打印一个以 \0 结尾的字符串(默认黑底白字)
void console_write(char *cstr)
{
        bool intr_flag = false;
        local_intr_store(intr_flag);
        {
                while (*cstr) {
                        console_putc_color(*cstr++, rc_black, rc_white);
                }
                _flush_console_current();
        }
        local_intr_restore(intr_flag);
}
예제 #30
0
// 屏幕打印一个以 \0 结尾的字符串(带颜色)
void console_write_color(char *cstr, real_color_t back, real_color_t fore)
{
        bool intr_flag = false;
        local_intr_store(intr_flag);
        {
                while (*cstr) {
                        console_putc_color(*cstr++, back, fore);
                }
                _flush_console_current();
        }
        local_intr_restore(intr_flag);
}