Changeset bb252ca in mainline


Ignore:
Timestamp:
2010-05-02T20:58:27Z (14 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
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/mm/as.h

    r4ce914d4 rbb252ca  
    11/*
    2  * Copyright (c) 2001-2004 Jakub Jermar
     2 * Copyright (c) 2010 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    227227extern void as_init(void);
    228228
    229 extern as_t *as_create(int flags);
    230 extern void as_destroy(as_t *as);
    231 extern void as_switch(as_t *old_as, as_t *new_as);
    232 extern int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate);
    233 
    234 extern as_area_t *as_area_create(as_t *as, int flags, size_t size,
    235     uintptr_t base, int attrs, mem_backend_t *backend,
    236     mem_backend_data_t *backend_data);
    237 extern int as_area_destroy(as_t *as, uintptr_t address);       
    238 extern int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags);
    239 int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
    240     as_t *dst_as, uintptr_t dst_base, int dst_flags_mask);
    241 extern int as_area_change_flags(as_t *as, int flags, uintptr_t address);
    242 
    243 extern int as_area_get_flags(as_area_t *area);
    244 extern bool as_area_check_access(as_area_t *area, pf_access_t access);
    245 extern size_t as_area_get_size(uintptr_t base);
    246 extern int used_space_insert(as_area_t *a, uintptr_t page, size_t count);
    247 extern int used_space_remove(as_area_t *a, uintptr_t page, size_t count);
     229extern as_t *as_create(int);
     230extern void as_destroy(as_t *);
     231extern void as_hold(as_t *);
     232extern void as_release(as_t *);
     233extern void as_switch(as_t *, as_t *);
     234extern int as_page_fault(uintptr_t, pf_access_t, istate_t *);
     235
     236extern as_area_t *as_area_create(as_t *, int, size_t, uintptr_t, int,
     237    mem_backend_t *, mem_backend_data_t *);
     238extern int as_area_destroy(as_t *, uintptr_t);
     239extern int as_area_resize(as_t *, uintptr_t, size_t, int);
     240extern int as_area_share(as_t *, uintptr_t, size_t, as_t *, uintptr_t, int);
     241extern int as_area_change_flags(as_t *, int, uintptr_t);
     242
     243extern int as_area_get_flags(as_area_t *);
     244extern bool as_area_check_access(as_area_t *, pf_access_t);
     245extern size_t as_area_get_size(uintptr_t);
     246extern int used_space_insert(as_area_t *, uintptr_t, size_t);
     247extern int used_space_remove(as_area_t *, uintptr_t, size_t);
    248248
    249249
    250250/* Interface to be implemented by architectures. */
    251251#ifndef as_constructor_arch
    252 extern int as_constructor_arch(as_t *as, int flags);
     252extern int as_constructor_arch(as_t *, int);
    253253#endif /* !def as_constructor_arch */
    254254#ifndef as_destructor_arch
    255 extern int as_destructor_arch(as_t *as);
     255extern int as_destructor_arch(as_t *);
    256256#endif /* !def as_destructor_arch */
    257257#ifndef as_create_arch
    258 extern int as_create_arch(as_t *as, int flags);
     258extern int as_create_arch(as_t *, int);
    259259#endif /* !def as_create_arch */
    260260#ifndef as_install_arch
    261 extern void as_install_arch(as_t *as);
     261extern void as_install_arch(as_t *);
    262262#endif /* !def as_install_arch */
    263263#ifndef as_deinstall_arch
    264 extern void as_deinstall_arch(as_t *as);
     264extern void as_deinstall_arch(as_t *);
    265265#endif /* !def as_deinstall_arch */
    266266
     
    277277#define ELD_F_LOADER    1
    278278
    279 extern unsigned int elf_load(elf_header_t *header, as_t *as, int flags);
     279extern unsigned int elf_load(elf_header_t *, as_t *, int);
    280280
    281281/* Address space area related syscalls. */
    282 extern unative_t sys_as_area_create(uintptr_t address, size_t size, int flags);
    283 extern unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags);
    284 extern unative_t sys_as_area_change_flags(uintptr_t address, int flags);
    285 extern unative_t sys_as_area_destroy(uintptr_t address);
     282extern unative_t sys_as_area_create(uintptr_t, size_t, int);
     283extern unative_t sys_as_area_resize(uintptr_t, size_t, int);
     284extern unative_t sys_as_area_change_flags(uintptr_t, int);
     285extern unative_t sys_as_area_destroy(uintptr_t);
    286286
    287287/* Introspection functions. */
    288 extern void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize);
    289 extern void as_print(as_t *as);
     288extern void as_get_area_info(as_t *, as_area_info_t **, size_t *);
     289extern void as_print(as_t *);
    290290
    291291#endif /* KERNEL */
  • kernel/generic/include/proc/task.h

    r4ce914d4 rbb252ca  
    11/*
    2  * Copyright (c) 2001-2004 Jakub Jermar
     2 * Copyright (c) 2010 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    131131extern void task_init(void);
    132132extern void task_done(void);
    133 extern task_t *task_create(as_t *as, const char *name);
    134 extern void task_destroy(task_t *t);
    135 extern task_t *task_find_by_id(task_id_t id);
    136 extern int task_kill(task_id_t id);
    137 extern void task_get_accounting(task_t *t, uint64_t *ucycles, uint64_t *kcycles);
     133extern task_t *task_create(as_t *, const char *);
     134extern void task_destroy(task_t *);
     135extern void task_hold(task_t *);
     136extern void task_release(task_t *);
     137extern task_t *task_find_by_id(task_id_t);
     138extern int task_kill(task_id_t);
     139extern void task_get_accounting(task_t *, uint64_t *, uint64_t *);
    138140extern void task_print_list(void);
    139141
    140 extern void cap_set(task_t *t, cap_t caps);
    141 extern cap_t cap_get(task_t *t);
     142extern void cap_set(task_t *, cap_t);
     143extern cap_t cap_get(task_t *);
    142144
    143145#ifndef task_create_arch
    144 extern void task_create_arch(task_t *t);
     146extern void task_create_arch(task_t *);
    145147#endif
    146148
    147149#ifndef task_destroy_arch
    148 extern void task_destroy_arch(task_t *t);
     150extern void task_destroy_arch(task_t *);
    149151#endif
    150152
    151 extern unative_t sys_task_get_id(task_id_t *uspace_task_id);
    152 extern unative_t sys_task_set_name(const char *uspace_name, size_t name_len);
     153extern unative_t sys_task_get_id(task_id_t *);
     154extern unative_t sys_task_set_name(const char *, size_t);
    153155
    154156#endif
  • 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.