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

Changeset 057e77f in mainline


Ignore:
Timestamp:
2012-07-16T15:31:56Z (10 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial
Children:
0cf813d
Parents:
0594c7ea
Message:

preemption_disable: Removed failed attempt at rescheduling once preemption is enabled (and needed). Once again, preemption_enable() never reschedules.

Location:
kernel/generic
Files:
3 edited

Legend:

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

    r0594c7ea r057e77f  
    4040#include <debug.h>
    4141
    42 #define PREEMPTION_INC         (1 << 1)
    43 #define PREEMPTION_NEEDED_FLAG (1 << 0)
    44 #define PREEMPTION_NEEDED      (THE->preemption & PREEMPTION_NEEDED_FLAG)
     42#define PREEMPTION_INC         (1 << 0)
    4543#define PREEMPTION_DISABLED    (PREEMPTION_INC <= THE->preemption)
    4644#define PREEMPTION_ENABLED     (!PREEMPTION_DISABLED)
     
    5351        } while (0)
    5452
    55 /** Restores preemption and reschedules if out time slice already elapsed.*/
     53/** Restores preemption but never reschedules. */
    5654#define preemption_enable() \
    57         do { \
    58                 preemption_enable_noresched(); \
    59                 \
    60                 if (PREEMPTION_ENABLED && PREEMPTION_NEEDED) { \
    61                         preemption_enabled_scheduler(); \
    62                 } \
    63         } while (0)
    64 
    65 /** Restores preemption but never reschedules. */
    66 #define preemption_enable_noresched() \
    6755        do { \
    6856                ASSERT(PREEMPTION_DISABLED); \
     
    7260
    7361
    74 extern void preemption_enabled_scheduler(void);
    75 extern void preemption_set_needed(void);
    76 extern void preemption_clear_needed(void);
    77 
    7862#endif
    7963
  • kernel/generic/src/preempt/preemption.c

    r0594c7ea r057e77f  
    3737
    3838#include <preemption.h>
    39 #include <proc/scheduler.h>
    4039
    41 
    42 /** Determines if we are executing an exception/interrupt handler. */
    43 static bool in_exc_handler(void)
    44 {
    45         /* Err on the safe side until all exception processing code is audited. */
    46         return true;
    47 }
    48 
    49 /** Preemption was enabled. Calls scheduler(). */
    50 void preemption_enabled_scheduler(void)
    51 {
    52         ASSERT(PREEMPTION_ENABLED);
    53         ASSERT(PREEMPTION_NEEDED);
    54        
    55         /*
    56          * Avoid a race between a thread about to invoke the scheduler()
    57          * after checking THREAD->need_resched and an interrupt that
    58          * occurs right after the check.
    59          *
    60          * Also ensures that code that relies on disabled interrupts
    61          * to suppress preemption continues to work.
    62          */
    63         if (!interrupts_disabled() && !in_exc_handler()) {
    64                 preemption_clear_needed();
    65                 /* We may be preempted here, so we'll scheduler() again. Too bad. */
    66                 scheduler();
    67         }
    68 }
    69 
    70 /** Sets a flag to reschedule the next time preemption is enabled. */
    71 void preemption_set_needed(void)
    72 {
    73         /* No need to disable interrupts. */
    74         THE->preemption |= PREEMPTION_NEEDED_FLAG;
    75 }
    76 
    77 /** Instructs not to reschedule immediately when preemption is enabled. */
    78 void preemption_clear_needed(void)
    79 {
    80         /* No need to disable interrupts. */
    81         THE->preemption &= ~PREEMPTION_NEEDED_FLAG;
    82 }
    8340
    8441/** @}
  • kernel/generic/src/time/clock.c

    r0594c7ea r057e77f  
    212212                irq_spinlock_unlock(&THREAD->lock, false);
    213213               
    214                 if (ticks == 0) {
    215                         if (PREEMPTION_ENABLED) {
    216                                 scheduler();
     214                if (ticks == 0 && PREEMPTION_ENABLED) {
     215                        scheduler();
    217216#ifdef CONFIG_UDEBUG
    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();
     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();
    225224#endif
    226                         } else {
    227                                 preemption_set_needed();
    228                         }
    229225                }
    230226        }
Note: See TracChangeset for help on using the changeset viewer.