Create new thread * * Create a new thread. * * @param func Thread's implementing function. * @param arg Thread's implementing function argument. * @param task Task to which the thread belongs. The caller must * guarantee that the task won't cease to exist during the * call. The task's lock may not be held. * @param flags Thread flags.
| 339 | * |
| 340 | */ |
| 341 | thread_t *thread_create(void (*func)(void *), void *arg, task_t *task, |
| 342 | thread_flags_t flags, const char *name) |
| 343 | { |
| 344 | thread_t *thread = (thread_t *) slab_alloc(thread_cache, FRAME_ATOMIC); |
| 345 | if (!thread) |
| 346 | return NULL; |
| 347 | |
| 348 | if (thread_create_arch(thread, flags) != EOK) { |
| 349 | slab_free(thread_cache, thread); |
| 350 | return NULL; |
| 351 | } |
| 352 | |
| 353 | /* Not needed, but good for debugging */ |
| 354 | memsetb(thread->kstack, STACK_SIZE, 0); |
| 355 | |
| 356 | irq_spinlock_lock(&tidlock, true); |
| 357 | thread->tid = ++last_tid; |
| 358 | irq_spinlock_unlock(&tidlock, true); |
| 359 | |
| 360 | memset(&thread->saved_context, 0, sizeof(thread->saved_context)); |
| 361 | context_set(&thread->saved_context, FADDR(cushion), |
| 362 | (uintptr_t) thread->kstack, STACK_SIZE); |
| 363 | |
| 364 | current_initialize((current_t *) thread->kstack); |
| 365 | |
| 366 | ipl_t ipl = interrupts_disable(); |
| 367 | thread->saved_context.ipl = interrupts_read(); |
| 368 | interrupts_restore(ipl); |
| 369 | |
| 370 | str_cpy(thread->name, THREAD_NAME_BUFLEN, name); |
| 371 | |
| 372 | thread->thread_code = func; |
| 373 | thread->thread_arg = arg; |
| 374 | thread->ticks = -1; |
| 375 | thread->ucycles = 0; |
| 376 | thread->kcycles = 0; |
| 377 | thread->uncounted = |
| 378 | ((flags & THREAD_FLAG_UNCOUNTED) == THREAD_FLAG_UNCOUNTED); |
| 379 | thread->priority = -1; /* Start in rq[0] */ |
| 380 | thread->cpu = NULL; |
| 381 | thread->wired = false; |
| 382 | thread->stolen = false; |
| 383 | thread->uspace = |
| 384 | ((flags & THREAD_FLAG_USPACE) == THREAD_FLAG_USPACE); |
| 385 | |
| 386 | thread->nomigrate = 0; |
| 387 | thread->state = Entering; |
| 388 | |
| 389 | timeout_initialize(&thread->sleep_timeout); |
| 390 | thread->sleep_interruptible = false; |
| 391 | thread->sleep_composable = false; |
| 392 | thread->sleep_queue = NULL; |
| 393 | thread->timeout_pending = false; |
| 394 | |
| 395 | thread->in_copy_from_uspace = false; |
| 396 | thread->in_copy_to_uspace = false; |
| 397 | |
| 398 | thread->interrupted = false; |