Ignore:
File:
1 edited

Legend:

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

    r07d4271 r5a5269d  
    158158                return rc;
    159159
     160        atomic_store(&task->refcount, 0);
    160161        atomic_store(&task->lifecount, 0);
    161162
     
    200201        if (!task)
    201202                return NULL;
    202 
    203         refcount_init(&task->refcount);
    204203
    205204        task_create_arch(task);
     
    225224
    226225        task->answerbox.active = true;
    227 
    228         task->debug_sections = NULL;
    229226
    230227#ifdef CONFIG_UDEBUG
     
    269266 *
    270267 */
    271 static void task_destroy(task_t *task)
     268void task_destroy(task_t *task)
    272269{
    273270        /*
     
    300297void task_hold(task_t *task)
    301298{
    302         refcount_up(&task->refcount);
     299        atomic_inc(&task->refcount);
    303300}
    304301
     
    312309void task_release(task_t *task)
    313310{
    314         if (refcount_down(&task->refcount))
     311        if ((atomic_predec(&task->refcount)) == 0)
    315312                task_destroy(task);
    316313}
     
    388385        irq_spinlock_lock(&tasks_lock, true);
    389386        irq_spinlock_lock(&TASK->lock, false);
     387        irq_spinlock_lock(&threads_lock, false);
    390388
    391389        /* Set task name */
    392390        str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
    393391
     392        irq_spinlock_unlock(&threads_lock, false);
    394393        irq_spinlock_unlock(&TASK->lock, false);
    395394        irq_spinlock_unlock(&tasks_lock, true);
     
    417416/** Find task structure corresponding to task ID.
    418417 *
     418 * The tasks_lock must be already held by the caller of this function and
     419 * interrupts must be disabled.
     420 *
    419421 * @param id Task ID.
    420422 *
    421  * @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.
    422424 *
    423425 */
    424426task_t *task_find_by_id(task_id_t id)
    425427{
    426         task_t *task = NULL;
    427 
    428         irq_spinlock_lock(&tasks_lock, true);
     428        assert(interrupts_disabled());
     429        assert(irq_spinlock_locked(&tasks_lock));
    429430
    430431        odlink_t *odlink = odict_find_eq(&tasks, &id, NULL);
    431         if (odlink != NULL) {
    432                 task = odict_get_instance(odlink, task_t, ltasks);
    433 
    434                 /*
    435                  * The directory of tasks can't hold a reference, since that would
    436                  * prevent task from ever being destroyed. That means we have to
    437                  * check for the case where the task is already being destroyed, but
    438                  * not yet removed from the directory.
    439                  */
    440                 if (!refcount_try_up(&task->refcount))
    441                         task = NULL;
    442         }
    443 
    444         irq_spinlock_unlock(&tasks_lock, true);
    445 
    446         return task;
     432        if (odlink != NULL)
     433                return odict_get_instance(odlink, task_t, ltasks);
     434
     435        return NULL;
    447436}
    448437
     
    517506        /* Current values of threads */
    518507        list_foreach(task->threads, th_link, thread_t, thread) {
     508                irq_spinlock_lock(&thread->lock, false);
     509
    519510                /* Process only counted threads */
    520511                if (!thread->uncounted) {
     
    524515                        }
    525516
    526                         uret += atomic_time_read(&thread->ucycles);
    527                         kret += atomic_time_read(&thread->kcycles);
     517                        uret += thread->ucycles;
     518                        kret += thread->kcycles;
    528519                }
     520
     521                irq_spinlock_unlock(&thread->lock, false);
    529522        }
    530523
     
    535528static void task_kill_internal(task_t *task)
    536529{
    537         irq_spinlock_lock(&task->lock, true);
     530        irq_spinlock_lock(&task->lock, false);
     531        irq_spinlock_lock(&threads_lock, false);
    538532
    539533        /*
     
    542536
    543537        list_foreach(task->threads, th_link, thread_t, thread) {
    544                 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);
    545550        }
    546551
    547         irq_spinlock_unlock(&task->lock, true);
     552        irq_spinlock_unlock(&threads_lock, false);
     553        irq_spinlock_unlock(&task->lock, false);
    548554}
    549555
     
    563569                return EPERM;
    564570
     571        irq_spinlock_lock(&tasks_lock, true);
     572
    565573        task_t *task = task_find_by_id(id);
    566         if (!task)
     574        if (!task) {
     575                irq_spinlock_unlock(&tasks_lock, true);
    567576                return ENOENT;
     577        }
    568578
    569579        task_kill_internal(task);
    570         task_release(task);
     580        irq_spinlock_unlock(&tasks_lock, true);
     581
    571582        return EOK;
    572583}
     
    598609        }
    599610
     611        irq_spinlock_lock(&tasks_lock, true);
    600612        task_kill_internal(TASK);
     613        irq_spinlock_unlock(&tasks_lock, true);
     614
    601615        thread_exit();
    602616}
     
    627641        if (additional)
    628642                printf("%-8" PRIu64 " %9zu", task->taskid,
    629                     atomic_load(&task->lifecount));
     643                    atomic_load(&task->refcount));
    630644        else
    631645                printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %10p %10p"
     
    639653                printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c "
    640654                    "%9zu\n", task->taskid, ucycles, usuffix, kcycles,
    641                     ksuffix, atomic_load(&task->lifecount));
     655                    ksuffix, atomic_load(&task->refcount));
    642656        else
    643657                printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %18p %18p\n",
Note: See TracChangeset for help on using the changeset viewer.