Changeset 057e77f in mainline
- Timestamp:
- 2012-07-16T15:31:56Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0cf813d
- Parents:
- 0594c7ea
- Location:
- kernel/generic
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/preemption.h
r0594c7ea r057e77f 40 40 #include <debug.h> 41 41 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) 45 43 #define PREEMPTION_DISABLED (PREEMPTION_INC <= THE->preemption) 46 44 #define PREEMPTION_ENABLED (!PREEMPTION_DISABLED) … … 53 51 } while (0) 54 52 55 /** Restores preemption and reschedules if out time slice already elapsed.*/53 /** Restores preemption but never reschedules. */ 56 54 #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() \67 55 do { \ 68 56 ASSERT(PREEMPTION_DISABLED); \ … … 72 60 73 61 74 extern void preemption_enabled_scheduler(void);75 extern void preemption_set_needed(void);76 extern void preemption_clear_needed(void);77 78 62 #endif 79 63 -
kernel/generic/src/preempt/preemption.c
r0594c7ea r057e77f 37 37 38 38 #include <preemption.h> 39 #include <proc/scheduler.h>40 39 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 that58 * occurs right after the check.59 *60 * Also ensures that code that relies on disabled interrupts61 * 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 }83 40 84 41 /** @} -
kernel/generic/src/time/clock.c
r0594c7ea r057e77f 212 212 irq_spinlock_unlock(&THREAD->lock, false); 213 213 214 if (ticks == 0) { 215 if (PREEMPTION_ENABLED) { 216 scheduler(); 214 if (ticks == 0 && PREEMPTION_ENABLED) { 215 scheduler(); 217 216 #ifdef CONFIG_UDEBUG 218 219 220 221 222 223 224 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(); 225 224 #endif 226 } else {227 preemption_set_needed();228 }229 225 } 230 226 }
Note:
See TracChangeset
for help on using the changeset viewer.