Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/task.c

    rf35749e r5a5269d  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
    32 * Copyright (c) 2010 Jakub Jermar
     3 * Copyright (c) 2018 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    104104 *
    105105 */
    106 void task_done(task_t *cur_task)
     106void task_done(void)
    107107{
    108108        size_t tasks_left;
     
    112112                task_t *task_0 = ipc_box_0->task;
    113113                ipc_box_0 = NULL;
    114 
    115114                /*
    116115                 * The first task is held by kinit(), we need to release it or
     
    130129                task = task_first();
    131130                while (task != NULL) {
    132                         if (task != cur_task) {
     131                        if (task != TASK) {
    133132                                tasks_left++;
    134133#ifdef CONFIG_DEBUG
     
    159158                return rc;
    160159
     160        atomic_store(&task->refcount, 0);
    161161        atomic_store(&task->lifecount, 0);
    162162
     
    201201        if (!task)
    202202                return NULL;
    203 
    204         refcount_init(&task->refcount);
    205203
    206204        task_create_arch(task);
     
    226224
    227225        task->answerbox.active = true;
    228 
    229         task->debug_sections = NULL;
    230226
    231227#ifdef CONFIG_UDEBUG
     
    270266 *
    271267 */
    272 static void task_destroy(task_t *task)
     268void task_destroy(task_t *task)
    273269{
    274270        /*
     
    301297void task_hold(task_t *task)
    302298{
    303         refcount_up(&task->refcount);
     299        atomic_inc(&task->refcount);
    304300}
    305301
     
    313309void task_release(task_t *task)
    314310{
    315         if (refcount_down(&task->refcount))
     311        if ((atomic_predec(&task->refcount)) == 0)
    316312                task_destroy(task);
    317313}
     
    389385        irq_spinlock_lock(&tasks_lock, true);
    390386        irq_spinlock_lock(&TASK->lock, false);
     387        irq_spinlock_lock(&threads_lock, false);
    391388
    392389        /* Set task name */
    393390        str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
    394391
     392        irq_spinlock_unlock(&threads_lock, false);
    395393        irq_spinlock_unlock(&TASK->lock, false);
    396394        irq_spinlock_unlock(&tasks_lock, true);
     
    418416/** Find task structure corresponding to task ID.
    419417 *
     418 * The tasks_lock must be already held by the caller of this function and
     419 * interrupts must be disabled.
     420 *
    420421 * @param id Task ID.
    421422 *
    422  * @return Task reference or NULL if there is no such task ID.
     423 * @return Task structure address or NULL if there is no such task ID.
    423424 *
    424425 */
    425426task_t *task_find_by_id(task_id_t id)
    426427{
    427         task_t *task = NULL;
    428 
    429         irq_spinlock_lock(&tasks_lock, true);
     428        assert(interrupts_disabled());
     429        assert(irq_spinlock_locked(&tasks_lock));
    430430
    431431        odlink_t *odlink = odict_find_eq(&tasks, &id, NULL);
    432         if (odlink != NULL) {
    433                 task = odict_get_instance(odlink, task_t, ltasks);
    434 
    435                 /*
    436                  * The directory of tasks can't hold a reference, since that would
    437                  * prevent task from ever being destroyed. That means we have to
    438                  * check for the case where the task is already being destroyed, but
    439                  * not yet removed from the directory.
    440                  */
    441                 if (!refcount_try_up(&task->refcount))
    442                         task = NULL;
    443         }
    444 
    445         irq_spinlock_unlock(&tasks_lock, true);
    446 
    447         return task;
     432        if (odlink != NULL)
     433                return odict_get_instance(odlink, task_t, ltasks);
     434
     435        return NULL;
    448436}
    449437
     
    518506        /* Current values of threads */
    519507        list_foreach(task->threads, th_link, thread_t, thread) {
     508                irq_spinlock_lock(&thread->lock, false);
     509
    520510                /* Process only counted threads */
    521511                if (!thread->uncounted) {
     
    525515                        }
    526516
    527                         uret += atomic_time_read(&thread->ucycles);
    528                         kret += atomic_time_read(&thread->kcycles);
     517                        uret += thread->ucycles;
     518                        kret += thread->kcycles;
    529519                }
     520
     521                irq_spinlock_unlock(&thread->lock, false);
    530522        }
    531523
     
    536528static void task_kill_internal(task_t *task)
    537529{
    538         irq_spinlock_lock(&task->lock, true);
     530        irq_spinlock_lock(&task->lock, false);
     531        irq_spinlock_lock(&threads_lock, false);
    539532
    540533        /*
     
    543536
    544537        list_foreach(task->threads, th_link, thread_t, thread) {
    545                 thread_interrupt(thread);
     538                bool sleeping = false;
     539
     540                irq_spinlock_lock(&thread->lock, false);
     541
     542                thread->interrupted = true;
     543                if (thread->state == Sleeping)
     544                        sleeping = true;
     545
     546                irq_spinlock_unlock(&thread->lock, false);
     547
     548                if (sleeping)
     549                        waitq_interrupt_sleep(thread);
    546550        }
    547551
    548         irq_spinlock_unlock(&task->lock, true);
     552        irq_spinlock_unlock(&threads_lock, false);
     553        irq_spinlock_unlock(&task->lock, false);
    549554}
    550555
     
    564569                return EPERM;
    565570
     571        irq_spinlock_lock(&tasks_lock, true);
     572
    566573        task_t *task = task_find_by_id(id);
    567         if (!task)
     574        if (!task) {
     575                irq_spinlock_unlock(&tasks_lock, true);
    568576                return ENOENT;
     577        }
    569578
    570579        task_kill_internal(task);
    571         task_release(task);
     580        irq_spinlock_unlock(&tasks_lock, true);
     581
    572582        return EOK;
    573583}
     
    599609        }
    600610
     611        irq_spinlock_lock(&tasks_lock, true);
    601612        task_kill_internal(TASK);
     613        irq_spinlock_unlock(&tasks_lock, true);
     614
    602615        thread_exit();
    603616}
     
    628641        if (additional)
    629642                printf("%-8" PRIu64 " %9zu", task->taskid,
    630                     atomic_load(&task->lifecount));
     643                    atomic_load(&task->refcount));
    631644        else
    632645                printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %10p %10p"
     
    640653                printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c "
    641654                    "%9zu\n", task->taskid, ucycles, usuffix, kcycles,
    642                     ksuffix, atomic_load(&task->lifecount));
     655                    ksuffix, atomic_load(&task->refcount));
    643656        else
    644657                printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %18p %18p\n",
Note: See TracChangeset for help on using the changeset viewer.