Esempio n. 1
0
void __noprof kernel_main_thread(void *data)
{
	struct thread *me = CURRENT();
	struct thread_queue tmp_q;

	tq_init(&tmp_q);
	tq_insert_head(me, &tmp_q);

	bug_on(!scheduler_enqueue(&tmp_q));

	mach_running();

	kprintf("Initializing vfs core... ");
	fs_init();
	kprintf("Done.\n");

	call_late_init();

	run_tests();

	load_init();

	for (;;) {
		scheduler_yield();
		arch_idle();
	}

	bug();
}
Esempio n. 2
0
t_status	interface_scheduler_yield(o_syscall*	message)
{
  t_status error;

  error = scheduler_yield();

  message->u.reply.error = error;

  return (STATUS_OK);
}
int main(void)
{
	config_clocks();
	config_gpio();
	scheduler_init();

	/* Start running the tasks. This call will never return. */
	scheduler_yield();

	return 0;
}
Esempio n. 4
0
void scheduler_terminateCurrentTask()
{
	log(LOG_DEBUG, "scheduler: Deleting current task <%s>\n", currentTask->name);

	if(currentTask->next == currentTask)
		currentTask = NULL;
	else
	{
		currentTask->next->last = currentTask->last;
		currentTask->last->next = currentTask->next;
	}

	scheduler_yield();
}
/* Fade an LED in and out in a sinusoidal fashion. */
static void blinkloop(float speed, uint16_t ledpin)
{
	while (true) {
		float step;
		unsigned i;
		for (step = -3.14; step < 3.14; step += speed) {
			unsigned duty = 128 + 128 * quicksine(step);

			gpio_clear(GPIOC, ledpin); /* LED off */
			for (i = 0; i < 256; i++) {
				if (i == duty) {
					gpio_set(GPIOC, ledpin); /* LED on */
				}

				/* Let the other tasks run */
				scheduler_yield();
			}
		}
	}
}
Esempio n. 6
0
struct sysret sys_yield(capaddr_t target)
{
    dispatcher_handle_t handle = dcb_current->disp;
    struct dispatcher_shared_generic *disp =
        get_dispatcher_shared_generic(handle);


    debug(SUBSYS_DISPATCH, "%.*s yields%s\n", DISP_NAME_LEN, disp->name,
          !disp->haswork && disp->lmp_delivered == disp->lmp_seen
           ? " and is removed from the runq" : "");

    if (!disp->disabled) {
        printk(LOG_ERR, "SYSCALL_YIELD while enabled\n");
        return SYSRET(SYS_ERR_CALLER_ENABLED);
    }

    struct capability *yield_to = NULL;
    if (target != CPTR_NULL) {
        errval_t err;

        /* directed yield */
        err = caps_lookup_cap(&dcb_current->cspace.cap, target, CPTR_BITS,
                              &yield_to, CAPRIGHTS_READ);
        if (err_is_fail(err)) {
            return SYSRET(err);
        } else if (yield_to == NULL ||
                   (yield_to->type != ObjType_EndPoint
                    && yield_to->type != ObjType_Dispatcher)) {
            return SYSRET(SYS_ERR_INVALID_YIELD_TARGET);
        }
        /* FIXME: check rights? */
    }

    disp->disabled = false;
    dcb_current->disabled = false;

    // Remove from queue when no work and no more messages and no missed wakeup
    systime_t wakeup = disp->wakeup;
    if (!disp->haswork && disp->lmp_delivered == disp->lmp_seen
        && (wakeup == 0 || wakeup > (kernel_now + kcb_current->kernel_off))) {

        trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_SCHED_REMOVE,
            (uint32_t)(lvaddr_t)dcb_current & 0xFFFFFFFF);
        trace_event(TRACE_SUBSYS_KERNEL, TRACE_EVENT_KERNEL_SCHED_REMOVE,
                151);

        scheduler_remove(dcb_current);
        if (wakeup != 0) {
            wakeup_set(dcb_current, wakeup);
        }
    } else {
        // Otherwise yield for the timeslice
        scheduler_yield(dcb_current);
    }

    if (yield_to != NULL) {
        struct dcb *target_dcb = NULL;
        if (yield_to->type == ObjType_EndPoint) {
            target_dcb = yield_to->u.endpoint.listener;
        } else if (yield_to->type == ObjType_Dispatcher) {
            target_dcb = yield_to->u.dispatcher.dcb;
        } else {
            panic("invalid type in yield cap");
        }

        trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_YIELD,
            (uint32_t)(lvaddr_t)target_dcb & 0xFFFFFFFF);
        make_runnable(target_dcb);
        dispatch(target_dcb);
    } else {
//        trace_event(TRACE_SUBSYS_BNET, TRACE_EVENT_BNET_YIELD,
//            0);

        /* undirected yield */
        dispatch(schedule());
    }

    panic("Yield returned!");
}
Esempio n. 7
0
int main(int argc, char **argv)
{
    int tasks = 0, alltasks = MAXTASKS, runtime, quantum = 1;

    if(argc < 3) {
        printf("Usage: %s <config.cfg> <runtime> [quantum]\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    runtime = atoi(argv[2]);
    if(argc >= 4) {
        quantum = atoi(argv[3]);
    }

    sched = malloc(sizeof(struct dcb) * runtime * alltasks);
    allptrs = calloc(alltasks, sizeof(struct dcb *));

    FILE *f = fopen(argv[1], "r");
    assert(f != NULL);
    bool readline = true;

    for(kernel_now = 0; kernel_now < runtime; kernel_now++) {
        unsigned long time, wcet, period, weight, id, blocktime, deadline, rd;
        char b[512], *r;

        for(;;) {
            if(readline) {
                do {
                    r = fgets(b, 512, f);
                } while(r != NULL && (b[0] == '#' || b[0] == '\n'));

                if(r == NULL) {
                    break;
                }
            } else {
                readline = true;
            }

            if((rd = sscanf(b, "%lu H %lu %lu %lu %lu", &time, &wcet, &period, &blocktime, &deadline)) >= 4) {
                if(time != kernel_now) { readline = false; break; }
                // Create new hard real-time task
                struct dcb *dcb = malloc(sizeof(struct dcb));
                init_dcb(dcb, tasks);
                dcb->type = TASK_TYPE_HARD_REALTIME;
                dcb->wcet = wcet;
                dcb->period = period;
                dcb->blocktime = blocktime;
                dcb->release_time = kernel_now;
                snprintf(dcb->dsg.name, DISP_NAME_LEN, "h %d", tasks);
                if(rd == 5) {
                    dcb->deadline = deadline;
                } else {
                    dcb->deadline = period;
                }
                make_runnable(dcb);
                assert(tasks < MAXTASKS);
                allptrs[tasks++] = dcb;
            } else if(sscanf(b, "%lu S %lu %lu", &time, &wcet, &period) == 3) {
                if(time != kernel_now) { readline = false; break; }
                // Create new soft real-time task
                struct dcb *dcb = malloc(sizeof(struct dcb));
                init_dcb(dcb, tasks);
                dcb->type = TASK_TYPE_SOFT_REALTIME;
                dcb->wcet = wcet;
                dcb->period = period;
                snprintf(dcb->dsg.name, DISP_NAME_LEN, "s %d", tasks);
                make_runnable(dcb);
                assert(tasks < MAXTASKS);
                allptrs[tasks++] = dcb;
            } else if(sscanf(b, "%lu B %lu", &time, &weight) == 2) {
                if(time != kernel_now) { readline = false; break; }
                // Create new best-effort task
                struct dcb *dcb = malloc(sizeof(struct dcb));
                init_dcb(dcb, tasks);
                dcb->type = TASK_TYPE_BEST_EFFORT;
                dcb->weight = weight;
                snprintf(dcb->dsg.name, DISP_NAME_LEN, "b %d", tasks);
                make_runnable(dcb);
                assert(tasks < MAXTASKS);
                allptrs[tasks++] = dcb;
            } else if(sscanf(b, "%lu d %lu", &time, &id) == 2) {
                if(time != kernel_now) { readline = false; break; }
                // Delete task with given ID
                assert(id < MAXTASKS);
                scheduler_remove(allptrs[id]);
            } else if(sscanf(b, "%lu r %lu", &time, &id) == 2) {
                if(time != kernel_now) { readline = false; break; }
                // Re-release task with given ID
                assert(id < MAXTASKS);
                if(allptrs[id]->type != TASK_TYPE_BEST_EFFORT) {
                    allptrs[id]->release_time = kernel_now;
                }
                make_runnable(allptrs[id]);
            } else if(sscanf(b, "%lu y %lu", &time, &id) == 2) {
                if(time != kernel_now) { readline = false; break; }
                // Yield task with given ID
                assert(id < MAXTASKS);
                scheduler_yield(allptrs[id]);
            } else if(sscanf(b, "%lu c %lu", &time, &id) == 2) {
                if(time != kernel_now) { readline = false; break; }
                // Context switch to task with given ID
                assert(id < MAXTASKS);
                dcb_current = allptrs[id];
                continue;
            } else {
                fprintf(stderr, "Invalid line: %s\n", b);
                abort();
            }

            dcb_current = schedule();
        }

        for(int i = 0; i < alltasks; i++) {
            struct dcb *cd = allptrs[i];
            if(cd != NULL) {
                cd->dispatched = false;

#if 0
                if(cd->type == TASK_TYPE_HARD_REALTIME) {
                    if(cd->etime >= cd->blocktime) {
                        scheduler_remove(cd);
                    }
                }
#endif
            }
        }

        if(kernel_now % quantum == 0) {
            dcb_current = schedule();
        }

        if(dcb_current != NULL) {
            dcb_current->dispatched = true;

            /* printf("%4d: dispatching %2d, release time: %4lu, deadline: %4lu, period: %3lu, WCET: %3lu/%3lu\n", kernel_now, dcb_current->id, dcb_current->release_time, dcb_current->deadline, dcb_current->period, dcb_current->etime, dcb_current->wcet); */
        }
        for(int i = 0; i < alltasks; i++) {
            if(allptrs[i] != NULL) {
                sched[kernel_now * alltasks + i] = *allptrs[i];
            }
        }
    }

    fclose(f);

    // Print schedule
    printf("     ");
    for(int t = 0; t < runtime; t++) {
        if(t % 1000 == 0) {
            printf("%d", (t / 1000) % 10);
        } else {
            printf(" ");
        }
    }
    printf("\n");
    printf("     ");
    for(int t = 0; t < runtime; t++) {
        if(t % 100 == 0) {
            printf("%d", (t / 100) % 10);
        } else {
            printf(" ");
        }
    }
    printf("\n");
    printf("     ");
    for(int t = 0; t < runtime; t++) {
        if(t % 10 == 0) {
            printf("%d", (t / 10) % 10);
        } else {
            printf(" ");
        }
    }
    printf("\n");

    printf("     ");
    for(int t = 0; t < runtime; t++) {
        printf("%d", t % 10);
    }
    printf("\n");

    for(int i = 0; i < tasks; i++) {
        struct dcb *ct = allptrs[i];
        printf("%c%2d: ", typechar(ct->type), i);
        for(int t = 0; t < runtime; t++) {
            struct dcb *s = &sched[t * alltasks + i];

            if(s->dispatched) {
                printf("#");
            } else {
                printf(" ");
            }
        }
        printf("\n");
        printf("     ");
        for(int t = 0; t < runtime; t++) {
            struct dcb *s = &sched[t * alltasks + i];

            if(s->release_time == t) {
                printf("r");
            } else {
                printf(" ");
            }
        }
        printf("\n");
    }

    free(sched);
    free(allptrs);
    return 0;
}