Esempio n. 1
0
struct thread *thread_init_stack(void *stack, size_t stack_sz,
	       	int priority, void *(*run)(void *), void *arg) {
	struct thread *thread = stack; /* Allocating at the bottom */

	/* Stack setting up */
	thread_stack_init(thread, stack_sz);

	/* General initialization and task setting up */
	thread_init(thread, priority, run, arg);

	return thread;

}
Esempio n. 2
0
struct thread *thread_alloc(void) {
	thread_pool_entry_t *block;
	struct thread *t;

	if (!(block = (thread_pool_entry_t *) pool_alloc(&thread_pool))) {
		return NULL;
	}
	memset(block, 0x53, sizeof(*block));

	t = &block->thread;

	thread_stack_init(t, STACK_SZ);

	return t;
}
Esempio n. 3
0
kernel_pid_t thread_create(char *stack, int stacksize, char priority, int flags, void *(*function)(void *arg), void *arg, const char *name)
{
    /* allocate our thread control block at the top of our stackspace */
#ifdef DEVELHELP
    int total_stacksize = stacksize;
#endif
    stacksize -= sizeof(tcb_t);

    /* align tcb address on 32bit boundary */
    unsigned int tcb_address = (unsigned int) stack + stacksize;

    if (tcb_address & 1) {
        tcb_address--;
        stacksize--;
    }

    if (tcb_address & 2) {
        tcb_address -= 2;
        stacksize -= 2;
    }

    tcb_t *cb = (tcb_t *) tcb_address;

    if (priority >= SCHED_PRIO_LEVELS) {
        return -EINVAL;
    }

#ifdef DEVELHELP
    if (flags & CREATE_STACKTEST) {
        /* assign each int of the stack the value of it's address */
        unsigned int *stackmax = (unsigned int *)((char *)stack + stacksize);
        unsigned int *stackp = (unsigned int *)stack;

        while (stackp < stackmax) {
            *stackp = (unsigned int)stackp;
            stackp++;
        }
    }
    else {
        /* create stack guard */
        *stack = (unsigned int)stack;
    }
#endif

    if (!inISR()) {
        dINT();
    }

    kernel_pid_t pid = KERNEL_PID_UNDEF;
    for (kernel_pid_t i = KERNEL_PID_FIRST; i <= KERNEL_PID_LAST; ++i) {
        if (sched_threads[i] == NULL) {
            pid = i;
            break;
        }
    }
    if (pid == KERNEL_PID_UNDEF) {
        DEBUG("thread_create(): too many threads!\n");

        if (!inISR()) {
            eINT();
        }

        return -EOVERFLOW;
    }

    sched_threads[pid] = cb;

    cb->pid = pid;
    cb->sp = thread_stack_init(function, arg, stack, stacksize);
    cb->stack_start = stack;

#ifdef DEVELHELP
    cb->stack_size = total_stacksize;
#endif

    cb->priority = priority;
    cb->status = 0;

    cb->rq_entry.next = NULL;
    cb->rq_entry.prev = NULL;

    cb->name = name;

    cb->wait_data = NULL;

    cb->msg_waiters.first = NULL;

    cib_init(&(cb->msg_queue), 0);
    cb->msg_array = NULL;

    sched_num_threads++;

    DEBUG("Created thread %s. PID: %" PRIkernel_pid ". Priority: %u.\n", name, cb->pid, priority);

    if (flags & CREATE_SLEEPING) {
        sched_set_status(cb, STATUS_SLEEPING);
    }
    else {
        sched_set_status(cb, STATUS_PENDING);

        if (!(flags & CREATE_WOUT_YIELD)) {
            if (!inISR()) {
                eINT();
                thread_yield();
            }
            else {
                sched_context_switch_request = 1;
            }
        }
    }

    if (!inISR() && sched_active_thread != NULL) {
        eINT();
    }

    return pid;
}