コード例 #1
0
ファイル: kernel.c プロジェクト: J-F-Sebastian/DiegOS
void thread_delay(unsigned msecs)
{
    thread_t *prev, *next;
    uint64_t st;
    uint64_t delay;

    if (!msecs)
        return;

    st = clock_get_ticks();
    delay = clock_convert_msecs_to_ticks(msecs);

    prev = scheduler_running_thread();

    if (!scheduler_delay_thread(st + delay)) {
        kernel_panic("cannot delay a thread.\n");
        return;
    }

    schedule_thread();

    next = scheduler_running_thread();

    switch_context(prev->context, next->context);
}
コード例 #2
0
ファイル: sched.c プロジェクト: crazy2k/zafio
void switch_tasks() {
    uint32_t eflags = disable_interrupts();

    task_t *old_task = current_task();

    task_t *current_candidate = old_task->next;
    task_t *first_candidate = current_candidate;
    task_t *selected = NULL;
    // Buscamos una tarea que este lista para ejecutarse. Si no hay ninguna,
    // hacemos halt hasta que ocurra una interrupcion.
    do {
        do {
            if (!(current_candidate->waiting)) {
                selected = current_candidate;
                break;
            }
            current_candidate = current_candidate->next;
        } while(current_candidate != first_candidate);
        
        if (selected == NULL) {
            outb(PIC1_DATA, (PIC_ALL_ENABLED & (~PIC_TIMER)) | PIC_TIMER);
            wait_for_interrupt();
            outb(PIC1_DATA, PIC_ALL_ENABLED);
        }

    } while (selected == NULL);

    task_list = selected;

    switch_context(old_task, current_task());

    restore_eflags(eflags);
}
コード例 #3
0
ファイル: timer.c プロジェクト: deepadevaraj/adix
/* Handles the timer. In this case, it's very simple: We
*  increment the 'timer_ticks' variable every time the
*  timer fires. By default, the timer fires 18.222 times
*  per second. Why 18.222Hz? Some engineer at IBM must've
*  been smoking something funky */
void timer_handler()
{
    static int once = 0;
    static char *video_buf = NULL;
    //printf("Timer interrupt");

    if(once == 0 || (uint64_t)video_buf != (((uint64_t)global_video_vaddr) + 4000))
    {
	once = 1;

	video_buf = (char*)(((uint64_t)global_video_vaddr) + 4000);     /* end of video memory */
	*(video_buf-2) = *(video_buf-4) = '0';
	*(video_buf-8) = *(video_buf-10) = '0';
	*(video_buf-14) = *(video_buf-16) = '0';
	*(video_buf-6) = *(video_buf-12) = ':';
    }

    /* Increment our 'tick count' */
    timer_ticks++;
	sys_wakeup_timer();
	/* Switch every 10ms */
	if(timer_ticks % 100 == 0){ 
    /* And yes, that's a 60 pointer CS506 project! :) Preemption! */
   		switch_context();
	}

    /* Every 18 clocks (approximately 1 second), we will
    *  display a message on the screen */
    if (timer_ticks % PIT_CLOCK_HZ == 0)
    {
        
		timer_ticks = 0;

		if(++time_sec == 60)
        {
            time_sec = 0;
	    	if(++time_min == 60)
            {

                 time_min = 0;
                 ++time_hour;

                 *(video_buf-16) = '0' + (time_hour/10);
                 *(video_buf-14) = '0' + (time_hour%10);
            }

            *(video_buf-10) = '0' + (time_min/10);
            *(video_buf-8) = '0' + (time_min%10);	    	
        } 

        *(video_buf-4) = '0' + (time_sec/10);
	*(video_buf-2) = '0' + (time_sec%10);

        //printf("%d:%d:%d\n",time_hour,time_min,time_sec);
    }
}
コード例 #4
0
ファイル: tasks.c プロジェクト: drewwalton19216801/eduOS
void reschedule(void)
{
	size_t** stack;
	uint8_t flags;

	flags = irq_nested_disable();
	if ((stack = scheduler()))
		switch_context(stack);
	irq_nested_enable(flags);
}
コード例 #5
0
ファイル: scheduler.c プロジェクト: jpdantur/SO2
void sched_sleep(int param_time, int pid)
{
	sleeping_pid=pid;
	sleep_time=param_time;
	//video_write_byte(param_time+'0');
	sleep_flag=1;
	set_state(pid,SLEEPING);
	//__print_debug("Entra aca");
	//__video_debug(pid+'0');
	switch_context();
}
コード例 #6
0
ファイル: task.c プロジェクト: marrony/kernel
void schedule() {
    struct task_t* old_task = current_task;

    current_task = current_task->next;

    if(!current_task)
        current_task = ready_queue_start;

    if(current_task != old_task)
        switch_context(&old_task->context, current_task->context);
}
コード例 #7
0
ファイル: threads.c プロジェクト: Agueeva/bert100
void
Thread_Switch(Thread * newTh)
{
	Thread *oldTh = g_CurrTh;
	g_CurrTh = newTh;
	stat_ContextSwitch++;
	newTh->nrUsed++;
	switch_context(&newTh->regSP, &oldTh->regSP);
	/*
	 ****************************************************************
	 * Everything below switch_registers will be done in the new
	 * context (or not at all if the new context was not left here).
	 ****************************************************************
	 */
}
コード例 #8
0
ファイル: thread.c プロジェクト: nielh/dragon
void thread_schedule()
{
	thread_t* target = thread_pick();
	assert(target);

	if(thread_current == target)
        return;

    s64 new_cr3 = 0;
	if(target->process)
    {
        new_cr3 = VIR2PHY(target->process->page_dir);
    }

    *(void**)PHY2VIR(tss64_rsp0) = target->kstack_end; // set rsp0
	switch_context(target, new_cr3);
}
コード例 #9
0
ファイル: base.c プロジェクト: ShunYao/OS502
void  Dispatcher(){

		while(readyHead == NULL && timerHead!= NULL)
	    {    
		   CALL(Z502Idle());
		}
		if(readyHead!=NULL)
		{

			    schedular_printer(READY);
				lockReady();
				CALL(makeReadyToRun(readyHead));
				current_PCB_PTR=makeReady;
				current_PCB_PTR->p_status = RUNNING;
				unlockReady();
				CALL(switch_context(current_PCB_PTR));
		}
 return;
}
コード例 #10
0
ファイル: kernel.c プロジェクト: J-F-Sebastian/DiegOS
void thread_lock_mutex(mutex_t *mtx)
{
    thread_t *prev, *next;
    BOOL is_locked;

    if (!mtx) {
        return;
    }

    prev = scheduler_running_thread();

    is_locked = mutex_is_locked(mtx);

    if (lock_mutex(prev->tid, mtx) && is_locked) {
        scheduler_wait_thread(THREAD_FLAG_WAIT_MUTEX);
        schedule_thread();
        next = scheduler_running_thread();
        switch_context(prev->context, next->context);
    }
}
コード例 #11
0
ファイル: kernel.c プロジェクト: J-F-Sebastian/DiegOS
void thread_suspend()
{
    thread_t *prev, *next;

    prev = scheduler_running_thread();

    if (!scheduler_suspend_thread()) {
        kernel_panic("cannot suspend a thread.\n");
        return;
    }

    schedule_thread();

    next = scheduler_running_thread();

    /* No one to wait for */
    if (prev == next) {
        return;
    }

    switch_context(prev->context, next->context);
}
コード例 #12
0
ファイル: scb.c プロジェクト: javimunhoz/vax-kernel
void timer_handler(void *arg) {

	tickcnt++;
	mtpr(0xc1, PR_ICCS);

	/* start multitask? */
	if ((sched_on == 1) && (sched_running == 0)) {
		sched_running = 1;
	}

	/* stop multitask? */
	if (current_process == 0) {
		if ((sched_on == 0) && (sched_running == 1)) {
			sched_running = 0;
		}
	}

	/* schedule? */
	if (sched_running) {
		switch_context(); /* schedule and pre-dispatch in clock IPL */
		mtpr(3, PR_SIRR); /* request soft int in IPL 3 to real hardware switch */
	}
}
コード例 #13
0
ファイル: PTRACE.C プロジェクト: OS2World/UTIL-DISK-HFSutils
int do_ptrace(int request, int child_id, DWORD addr, DWORD data, DWORD * ret)
{
    NEWPROCESS *child;

#ifdef CONFIG_KDEB
    if (child_id == 1)
        return KDEB_ptrace(request, addr, data, ret);
#endif

    if (!(child = find_process(child_id)))
        return EMX_ESRCH;

    if (child->pptr != npz || !(child->p_flags & PF_DEBUG))
        return EMX_ESRCH;

    if (child->p_status != PS_STOP)
        return EMX_ESRCH;

    *ret = 0;

    switch (request) {
    case PTRACE_TRACEME:
    case PTRACE_SESSION:
        return 0;

    case PTRACE_PEEKTEXT:
    case PTRACE_PEEKDATA:
        if (verify_illegal(child, addr, 4))
            return EMX_EIO;
        *ret = read32(child->data32sel, addr);
        return 0;

    case PTRACE_POKETEXT:
    case PTRACE_POKEDATA:
        if (verify_illegal(child, addr, 4))
            return EMX_EIO;
        if (dpmi10) {
            WORD page, pageorg;

            read32(child->data32sel, addr);	/* page in */
            if (GetPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &pageorg))
                return EMX_EIO;
            pageorg &= ~16;	/* don't modify access/dirty */
            page = pageorg | 8; /* read/write access */
            if (ModifyPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &page))
                return EMX_EIO;
            store32(child->data32sel, addr, data);
            ModifyPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &pageorg);
        } else
            store32(child->data32sel, addr, data);
        *ret = data;
        return 0;

    case PTRACE_EXIT:
        /* to do : switch to child -> do_signal(); */
        child->p_flags |= PF_WAIT_WAIT;
        return 0;

    case PTRACE_PEEKUSER:
        if (addr == 0x30) {	/* u_ar0  */
            *ret = 0xE0000000 + ((DWORD) (UINT) & (child->regs));
            return 0;
        } else {		/* peek regs */
            DWORD *peekat;
            peekat = (DWORD *) (UINT) (addr);

            if (peekat < &(child->regs.gs) || peekat > &(child->regs.ss))
                return EMX_EIO;

            *ret = *peekat;
            return 0;
        }

    case PTRACE_POKEUSER:
    {
        /* poke regs */
        DWORD *pokeat;

        pokeat = (DWORD *) (UINT) addr;

        if (pokeat < &(child->regs.gs) || pokeat > &(child->regs.ss))
            return EMX_EIO;

        /* change data for critical regs */
        if (pokeat == &(child->regs.eflags)) {
            data &= FLAG_MASK;
            data |= *pokeat & ~FLAG_MASK;
        } else if (pokeat <= &(child->regs.ds)
                   || pokeat == &(child->regs.cs))
            data = *pokeat;
        else if (pokeat == &(child->regs.esp)) {
            if (verify_illegal(child, data, 4))
                return EMX_EIO;
            child->regs.esp = data;
            child->regs.esporg = data + 12L;
        } else if (pokeat == &(child->regs.esporg)) {
            if (verify_illegal(child, data, 4))
                return EMX_EIO;
            child->regs.esporg = data;
            child->regs.esp = data - 12L;
        } else if (pokeat == &(child->regs.eip))
            if (verify_illegal(child, data, 4))
                return EMX_EIO;

        *pokeat = data;
        *ret = data;

        return 0;
    }

    case PTRACE_STEP:
        if ((int)data > 0 && (int)data <= MAX_SIGNALS)
            send_signal(child, (WORD) data);
        child->regs.eflags |= SINGLE_STEP;
        if (child->regs.esp == child->regs.esporg)
            child->regs.esp -= 12;

        npz->p_status = PS_STOP;
        switch_context(child);
        npz->p_status = PS_RUN;
        return 0;

    case PTRACE_RESUME:
        if ((int)data > 0 && (int)data <= MAX_SIGNALS)
            send_signal(child, (int) data);
        if (child->regs.esp == child->regs.esporg)
            child->regs.esp -= 12;

        npz->p_status = PS_STOP;
        switch_context(child);
        npz->p_status = PS_RUN;
        return 0;

    default:
        return EMX_EIO;
    }
}
コード例 #14
0
int daemon_main(int argc, char *argv[])
{
    int opt;
    bool fork_flag = false;
    bool replace_flag = false;
    bool patch_sepolicy = true;

    enum {
        OPT_ALLOW_ROOT_CLIENT = 1000,
        OPT_NO_PATCH_SEPOLICY = 1001,
        OPT_SIGSTOP_WHEN_READY = 1002,
        OPT_LOG_TO_KMSG = 1003,
        OPT_LOG_TO_STDIO = 1004,
        OPT_NO_UNSHARE = 1005,
    };

    static struct option long_options[] = {
        {"daemonize",          no_argument, 0, 'd'},
        {"replace",            no_argument, 0, 'r'},
        {"help",               no_argument, 0, 'h'},
        {"allow-root-client",  no_argument, 0, OPT_ALLOW_ROOT_CLIENT},
        {"no-patch-sepolicy",  no_argument, 0, OPT_NO_PATCH_SEPOLICY},
        {"sigstop-when-ready", no_argument, 0, OPT_SIGSTOP_WHEN_READY},
        {"log-to-kmsg",        no_argument, 0, OPT_LOG_TO_KMSG},
        {"log-to-stdio",       no_argument, 0, OPT_LOG_TO_STDIO},
        {"no-unshare",         no_argument, 0, OPT_NO_UNSHARE},
        {0, 0, 0, 0}
    };

    int long_index = 0;

    while ((opt = getopt_long(argc, argv, "drh", long_options, &long_index)) != -1) {
        switch (opt) {
        case 'd':
            fork_flag = true;
            break;

        case 'r':
            replace_flag = true;
            break;

        case 'h':
            daemon_usage(0);
            return EXIT_SUCCESS;

        case OPT_ALLOW_ROOT_CLIENT:
            allow_root_client = true;
            break;

        case OPT_NO_PATCH_SEPOLICY:
            patch_sepolicy = false;
            break;

        case OPT_SIGSTOP_WHEN_READY:
            sigstop_when_ready = true;
            break;

        case OPT_LOG_TO_KMSG:
            log_to_kmsg = true;
            break;

        case OPT_LOG_TO_STDIO:
            log_to_stdio = true;
            break;

        case OPT_NO_UNSHARE:
            no_unshare = true;
            break;

        default:
            daemon_usage(1);
            return EXIT_FAILURE;
        }
    }

    // There should be no other arguments
    if (argc - optind != 0) {
        daemon_usage(1);
        return EXIT_FAILURE;
    }

    if (!no_unshare && unshare(CLONE_NEWNS) < 0) {
        fprintf(stderr, "unshare() failed: %s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    if (patch_sepolicy) {
        patch_loaded_sepolicy(SELinuxPatch::MAIN);
    }

    if (!switch_context(MB_EXEC_CONTEXT)) {
        fprintf(stderr, "Failed to switch context; %s may not run properly",
                argv[0]);
    }

    if (replace_flag) {
        PROCTAB *proc = openproc(PROC_FILLCOM | PROC_FILLSTAT);
        if (proc) {
            pid_t curpid = getpid();

            while (proc_t *info = readproc(proc, nullptr)) {
                // NOTE: Can't check 'strcmp(info->cmd, "mbtool") == 0' (which
                // is the basename of /proc/<pid>/cmd) because the binary is not
                // always called "mbtool". For example, when run via SignedExec,
                // it's just called "binary".

                // If we can read the cmdline and argc >= 2
                if (info->cmdline && info->cmdline[0] && info->cmdline[1]) {
                    const char *name = strrchr(info->cmdline[0], '/');
                    if (name) {
                        ++name;
                    } else {
                        name = info->cmdline[0];
                    }

                    if (strcmp(name, "mbtool") == 0               // This is mbtool
                            && strstr(info->cmdline[1], "daemon") // And it's a daemon process
                            && info->tid != curpid) {             // And we're not killing ourself
                        // Kill the daemon process
                        LOGV("Killing PID %d", info->tid);
                        kill(info->tid, SIGTERM);
                    }
                }

                freeproc(info);
            }

            closeproc(proc);
        }

        // Give processes a chance to exit
        usleep(500000);
    }

    if (fork_flag) {
        run_daemon_fork();
    } else {
        return (daemon_init() && run_daemon())
                ? EXIT_SUCCESS : EXIT_FAILURE;
    }
}
コード例 #15
0
ファイル: sched.c プロジェクト: ChunHungLiu/xenomai
int __xnsched_run(struct xnsched *sched)
{
	struct xnthread *prev, *next, *curr;
	int switched, shadow;
	spl_t s;

	if (xnarch_escalate())
		return 0;

	trace_cobalt_schedule(sched);

	xnlock_get_irqsave(&nklock, s);

	curr = sched->curr;
	/*
	 * CAUTION: xnthread_host_task(curr) may be unsynced and even
	 * stale if curr = &rootcb, since the task logged by
	 * leave_root() may not still be the current one. Use
	 * "current" for disambiguating.
	 */
	xntrace_pid(current->pid, xnthread_current_priority(curr));
reschedule:
	switched = 0;
	if (!test_resched(sched))
		goto out;

	next = xnsched_pick_next(sched);
	if (next == curr) {
		if (unlikely(xnthread_test_state(next, XNROOT))) {
			if (sched->lflags & XNHTICK)
				xnintr_host_tick(sched);
			if (sched->lflags & XNHDEFER)
				xnclock_program_shot(&nkclock, sched);
		}
		goto out;
	}

	prev = curr;

	trace_cobalt_switch_context(prev, next);

	if (xnthread_test_state(next, XNROOT))
		xnsched_reset_watchdog(sched);

	sched->curr = next;
	shadow = 1;

	if (xnthread_test_state(prev, XNROOT)) {
		leave_root(prev);
		shadow = 0;
	} else if (xnthread_test_state(next, XNROOT)) {
		if (sched->lflags & XNHTICK)
			xnintr_host_tick(sched);
		if (sched->lflags & XNHDEFER)
			xnclock_program_shot(&nkclock, sched);
		enter_root(next);
	}

	xnstat_exectime_switch(sched, &next->stat.account);
	xnstat_counter_inc(&next->stat.csw);

	switch_context(sched, prev, next);

	/*
	 * Test whether we transitioned from primary mode to secondary
	 * over a shadow thread, caused by a call to xnthread_relax().
	 * In such a case, we are running over the regular schedule()
	 * tail code, so we have to skip our tail code.
	 */
	if (shadow && ipipe_root_p)
		goto shadow_epilogue;

	switched = 1;
	sched = xnsched_finish_unlocked_switch(sched);
	/*
	 * Re-read the currently running thread, this is needed
	 * because of relaxed/hardened transitions.
	 */
	curr = sched->curr;
	xnthread_switch_fpu(sched);
	xntrace_pid(current->pid, xnthread_current_priority(curr));
out:
	if (switched &&
	    xnsched_maybe_resched_after_unlocked_switch(sched))
		goto reschedule;

	if (curr->lock_count)
		sched->lflags |= XNINLOCK;

	xnlock_put_irqrestore(&nklock, s);

	return switched;

shadow_epilogue:
	__ipipe_complete_domain_migration();

	XENO_BUG_ON(COBALT, xnthread_current() == NULL);

	/*
	 * Interrupts must be disabled here (has to be done on entry
	 * of the Linux [__]switch_to function), but it is what
	 * callers expect, specifically the reschedule of an IRQ
	 * handler that hit before we call xnsched_run in
	 * xnthread_suspend() when relaxing a thread.
	 */
	XENO_BUG_ON(COBALT, !hard_irqs_disabled());

	return 1;
}