Changeset bb252ca in mainline for kernel/generic/src


Ignore:
Timestamp:
2010-05-02T20:58:27Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4872160
Parents:
4ce914d4 (diff), 1624aae (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge the scheduler fix.

Location:
kernel/generic/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/as.c

    r4ce914d4 rbb252ca  
    11/*
    2  * Copyright (c) 2001-2006 Jakub Jermar
     2 * Copyright (c) 2010 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    152152         * reference count never drops to zero.
    153153         */
    154         atomic_set(&AS_KERNEL->refcount, 1);
     154        as_hold(AS_KERNEL);
    155155}
    156156
     
    200200        DEADLOCK_PROBE_INIT(p_asidlock);
    201201
     202        ASSERT(as != AS);
    202203        ASSERT(atomic_get(&as->refcount) == 0);
    203204       
    204205        /*
    205          * Since there is no reference to this area,
    206          * it is safe not to lock its mutex.
     206         * Since there is no reference to this address space, it is safe not to
     207         * lock its mutex.
    207208         */
    208209
     
    225226        preemption_enable();    /* Interrupts disabled, enable preemption */
    226227        if (as->asid != ASID_INVALID && as != AS_KERNEL) {
    227                 if (as != AS && as->cpu_refcount == 0)
     228                if (as->cpu_refcount == 0)
    228229                        list_remove(&as->inactive_as_with_asid_link);
    229230                asid_put(as->asid);
     
    258259
    259260        slab_free(as_slab, as);
     261}
     262
     263/** Hold a reference to an address space.
     264 *
     265 * Holding a reference to an address space prevents destruction of that address
     266 * space.
     267 *
     268 * @param a             Address space to be held.
     269 */
     270void as_hold(as_t *as)
     271{
     272        atomic_inc(&as->refcount);
     273}
     274
     275/** Release a reference to an address space.
     276 *
     277 * The last one to release a reference to an address space destroys the address
     278 * space.
     279 *
     280 * @param a             Address space to be released.
     281 */
     282void as_release(as_t *as)
     283{
     284        if (atomic_predec(&as->refcount) == 0)
     285                as_destroy(as);
    260286}
    261287
  • kernel/generic/src/proc/scheduler.c

    r4ce914d4 rbb252ca  
    11/*
    2  * Copyright (c) 2001-2007 Jakub Jermar
     2 * Copyright (c) 2010 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    382382        int priority;
    383383        DEADLOCK_PROBE_INIT(p_joinwq);
     384        task_t *old_task = TASK;
     385        as_t *old_as = AS;
    384386
    385387        ASSERT(CPU != NULL);
    386388       
     389        /*
     390         * Hold the current task and the address space to prevent their
     391         * possible destruction should thread_destroy() be called on this or any
     392         * other processor while the scheduler is still using them.
     393         */
     394        if (old_task)
     395                task_hold(old_task);
     396        if (old_as)
     397                as_hold(old_as);
     398
    387399        if (THREAD) {
    388400                /* must be run after the switch to scheduler stack */
     
    476488         */
    477489        if (TASK != THREAD->task) {
    478                 as_t *as1 = NULL;
    479                 as_t *as2;
    480 
    481                 if (TASK) {
    482                         spinlock_lock(&TASK->lock);
    483                         as1 = TASK->as;
    484                         spinlock_unlock(&TASK->lock);
    485                 }
    486 
    487                 spinlock_lock(&THREAD->task->lock);
    488                 as2 = THREAD->task->as;
    489                 spinlock_unlock(&THREAD->task->lock);
     490                as_t *new_as = THREAD->task->as;
    490491               
    491492                /*
     
    493494                 * space.
    494495                 */
    495                 if (as1 != as2) {
     496                if (old_as != new_as) {
    496497                        /*
    497498                         * Both tasks and address spaces are different.
    498499                         * Replace the old one with the new one.
    499500                         */
    500                         as_switch(as1, as2);
     501                        as_switch(old_as, new_as);
    501502                }
     503
    502504                TASK = THREAD->task;
    503505                before_task_runs();
    504506        }
    505507
     508        if (old_task)
     509                task_release(old_task);
     510        if (old_as)
     511                as_release(old_as);
     512       
    506513        spinlock_lock(&THREAD->lock);   
    507514        THREAD->state = Running;
  • kernel/generic/src/proc/task.c

    r4ce914d4 rbb252ca  
    11/*
    2  * Copyright (c) 2001-2004 Jakub Jermar
     2 * Copyright (c) 2010 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    210210        btree_create(&ta->futexes);
    211211       
     212        /*
     213         * Get a reference to the address space.
     214         */
     215        as_hold(ta->as);
     216
    212217        ipl = interrupts_disable();
    213         atomic_inc(&as->refcount);
    214218        spinlock_lock(&tasks_lock);
    215219        ta->taskid = ++task_counter;
     
    250254         * Drop our reference to the address space.
    251255         */
    252         if (atomic_predec(&t->as->refcount) == 0)
    253                 as_destroy(t->as);
     256        as_release(t->as);
    254257       
    255258        slab_free(task_slab, t);
    256         TASK = NULL;
     259}
     260
     261/** Hold a reference to a task.
     262 *
     263 * Holding a reference to a task prevents destruction of that task.
     264 *
     265 * @param t             Task to be held.
     266 */
     267void task_hold(task_t *t)
     268{
     269        atomic_inc(&t->refcount);
     270}
     271
     272/** Release a reference to a task.
     273 *
     274 * The last one to release a reference to a task destroys the task.
     275 *
     276 * @param t             Task to be released.
     277 */
     278void task_release(task_t *t)
     279{
     280        if ((atomic_predec(&t->refcount)) == 0)
     281                task_destroy(t);
    257282}
    258283
  • kernel/generic/src/proc/thread.c

    r4ce914d4 rbb252ca  
    11/*
    2  * Copyright (c) 2001-2004 Jakub Jermar
     2 * Copyright (c) 2010 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    409409
    410410        /*
    411          * t is guaranteed to be the very last thread of its task.
    412          * It is safe to destroy the task.
     411         * Drop the reference to the containing task.
    413412         */
    414         if (atomic_predec(&t->task->refcount) == 0)
    415                 task_destroy(t->task);
     413        task_release(t->task);
    416414       
    417415        slab_free(thread_slab, t);
     
    436434        spinlock_lock(&task->lock);
    437435
    438         atomic_inc(&task->refcount);
     436        /* Hold a reference to the task. */
     437        task_hold(task);
    439438
    440439        /* Must not count kbox thread into lifecount */
Note: See TracChangeset for help on using the changeset viewer.