diff options
-rw-r--r-- | src/kernel/timemgr.C | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/kernel/timemgr.C b/src/kernel/timemgr.C index 39cb4b807..37d258029 100644 --- a/src/kernel/timemgr.C +++ b/src/kernel/timemgr.C @@ -26,6 +26,8 @@ #include <kernel/task.H> #include <kernel/cpumgr.H> #include <util/misc.H> +#include <kernel/misc.H> +#include <sys/task.h> uint64_t TimeManager::iv_timebaseFreq = 0xFFFFFFFF; @@ -154,6 +156,17 @@ bool TimeManager::simpleDelay(uint64_t i_sec, uint64_t i_nsec) uint64_t threshold = getTimeSliceCount()/YIELD_THRESHOLD_PER_SLICE; uint64_t delay = convertSecToTicks(i_sec, i_nsec); + bool isUserspace = !KernelMisc::in_kernel_mode(); + + // TB is not synchronized between cores, so if we're doing a poll we need + // to pin the task to the current cpu. Otherwise the getTB can get a + // drifted answer after a task migration. + if (isUserspace) + { + task_affinity_pin(); + } + + // Do polling delay. if(delay < threshold) { uint64_t expire = getCurrentTimeBase() + delay; @@ -165,6 +178,11 @@ bool TimeManager::simpleDelay(uint64_t i_sec, uint64_t i_nsec) result = true; } + if (isUserspace) + { + task_affinity_unpin(); + } + return result; } |