示例#1
0
文件: service.c 项目: zhoukk/service
struct queue *service_dispatch(struct monitor *monitor, struct queue *q) {
	if (!q) {
		q = worker_queue_pop();
		if (!q) return 0;
	}

	uint32_t handle = queue_handle(q);
	struct service *s = service_grab(handle);
	if (!s) {
		queue_release(q, queue_message_dtor, (void *)(uintptr_t)handle);
		return worker_queue_pop();
	}
	struct message m;
	if (!queue_pop(q, &m)) {
		service_release(handle);
		return worker_queue_pop();
	}
	int overload = queue_overload(q);
	if (overload)
		service_log(handle, "service may overload, message queue length = %d\n", overload);
	monitor_trigger(monitor, m.source, handle);
	if (s->logfile)
		log_output(s->logfile, &m);
	s->module.dispatch(s->handle, s->ud, &m);
	service_alloc(m.data, 0);
	monitor_trigger(monitor, 0, 0);
	struct queue *next = worker_queue_pop();
	if (next) {
		worker_queue_push(q);
		q = next;
	}
	service_release(handle);
	return q;
}
示例#2
0
void scheduler_rr(uint32_t sp)
{
    int i;
    int vm_count;
    int prev_vm_id;
    int next_vm_id;

    bool vm_valid;
    bool not_in_wfi;

    vm_count = sizeof(vm) / sizeof(guest);
    prev_vm_id = vm_id;
    next_vm_id = vm_id;

    //switch to other guests first if possible
    for(i = 0; i < vm_count; i++)
    {
        next_vm_id++;

        if(next_vm_id == vm_count)
        {
            next_vm_id = 0;
        }

        vm_valid = vm[next_vm_id].valid;
        not_in_wfi = vm[next_vm_id].sched.wfi_state != WFI_In;

        if(vm_valid && not_in_wfi)
        {
            //printm(d_scheduler, "vm switch, vm %d to vm %d", prev_vm_id, next_vm_id);

            //leaving from wfi
            if(vm[next_vm_id].sched.wfi_state == WFI_PendingIRQ)
            {
                printd(d_scheduler, "leave wfi");
                vm[next_vm_id].sched.wfi_state = WFI_Out;
                //scheduler_wait_gic_vcpu_if();
            }

            guest_suspend(&vm[prev_vm_id], sp);
            guest_restore(&vm[next_vm_id], sp);

            monitor_trigger(&sys_monitor, VM_SWITCH);

            scheduler_reset_timer();
            scheduler_leave_idle();
            return;
        }
    }

    //nothing to switch
    guest_suspend(&vm[prev_vm_id], sp);

    scheduler_reset_timer();
    scheduler_enter_idle();

    //never return
    idle_thread();
}