Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset b23c88e in mainline


Ignore:
Timestamp:
2012-07-11T05:45:48Z (10 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial
Children:
b68ae24
Parents:
9f8745c5
Message:

preemption_disable: Replaced memory barriers with compiler barriers. Added checks if reschedule is needed once preemption is enabled.

Location:
kernel/generic
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/arch.h

    r9f8745c5 rb23c88e  
    5353#define TASK                 THE->task
    5454#define AS                   THE->as
    55 #define PREEMPTION_DISABLED  THE->preemption_disabled
     55#define PREEMPTION_DISABLED  (0 != THE->preemption_disabled)
     56#define PREEMPTION_ENABLED   (0 == THE->preemption_disabled)
    5657#define MAGIC                UINT32_C(0xfacefeed)
    5758
  • kernel/generic/include/preemption.h

    r9f8745c5 rb23c88e  
    3838extern void preemption_disable(void);
    3939extern void preemption_enable(void);
     40extern void preemption_enable_noresched(void);
     41extern void preemption_enabled_scheduler(void);
     42
     43
    4044
    4145#endif
  • kernel/generic/include/proc/thread.h

    r9f8745c5 rb23c88e  
    155155        state_t state;
    156156       
     157        /** The thread would have been rescheduled had it not disabled preemption.*/
     158        bool need_resched;
     159       
    157160        /** Thread CPU. */
    158161        cpu_t *cpu;
  • kernel/generic/src/preempt/preemption.c

    r9f8745c5 rb23c88e  
    3838#include <preemption.h>
    3939#include <arch.h>
    40 #include <arch/asm.h>
    41 #include <arch/barrier.h>
     40#include <compiler/barrier.h>
    4241#include <debug.h>
     42#include <proc/scheduler.h>
    4343
    4444/** Increment preemption disabled counter. */
     
    4646{
    4747        THE->preemption_disabled++;
    48         memory_barrier();
     48        compiler_barrier();
    4949}
    5050
     
    5252void preemption_enable(void)
    5353{
     54        preemption_enable_noresched();
     55       
     56        if (PREEMPTION_ENABLED && THREAD && THREAD->need_resched) {
     57                preemption_enabled_scheduler();
     58        }
     59}
     60
     61/** Decrement preemption disabled counter. */
     62void preemption_enable_noresched(void)
     63{
    5464        ASSERT(PREEMPTION_DISABLED);
    55         memory_barrier();
     65        compiler_barrier();
    5666        THE->preemption_disabled--;
     67}
     68
     69/** Preemption was enabled. Calls scheduler(). */
     70void preemption_enabled_scheduler(void)
     71{
     72        ASSERT(PREEMPTION_ENABLED);
     73       
     74        /*
     75         * Avoid a race between a thread about to invoke the scheduler()
     76         * after checking THREAD->need_resched and an interrupt that
     77         * occurs right after the check.
     78         *
     79         * Also ensures that code that relies on disabled interrupts
     80         * to suppress preemption continues to work.
     81         */
     82        if (!interrupts_disabled()) {
     83                scheduler();
     84        }
    5785}
    5886
  • kernel/generic/src/proc/scheduler.c

    r9f8745c5 rb23c88e  
    404404        ASSERT((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
    405405        ASSERT(CPU != NULL);
     406        ASSERT(interrupts_disabled());
    406407       
    407408        /*
     
    419420                /* Must be run after the switch to scheduler stack */
    420421                after_thread_ran();
     422               
     423                THREAD->need_resched = false;
    421424               
    422425                switch (THREAD->state) {
  • kernel/generic/src/proc/thread.c

    r9f8745c5 rb23c88e  
    375375        thread->nomigrate = 0;
    376376        thread->state = Entering;
     377        thread->need_resched = false;
    377378       
    378379        timeout_initialize(&thread->sleep_timeout);
  • kernel/generic/src/time/clock.c

    r9f8745c5 rb23c88e  
    212212                irq_spinlock_unlock(&THREAD->lock, false);
    213213               
    214                 if ((!ticks) && (!PREEMPTION_DISABLED)) {
    215                         scheduler();
     214                if (ticks == 0) {
     215                        if (PREEMPTION_ENABLED) {
     216                                scheduler();
    216217#ifdef CONFIG_UDEBUG
    217                         /*
    218                          * Give udebug chance to stop the thread
    219                          * before it begins executing userspace code.
    220                          */
    221                         istate_t *istate = THREAD->udebug.uspace_state;
    222                         if ((istate) && (istate_from_uspace(istate)))
    223                                 udebug_before_thread_runs();
     218                                /*
     219                                * Give udebug chance to stop the thread
     220                                * before it begins executing userspace code.
     221                                */
     222                                istate_t *istate = THREAD->udebug.uspace_state;
     223                                if ((istate) && (istate_from_uspace(istate)))
     224                                        udebug_before_thread_runs();
    224225#endif
     226                        } else {
     227                                THREAD->need_resched = true;
     228                        }
    225229                }
    226230        }
Note: See TracChangeset for help on using the changeset viewer.