summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-08-16 21:04:41 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2014-08-16 21:04:41 +0200
commit773b57b676526975059e5ba3858cfde6d8b50ceb (patch)
treee0c4d5e398cb1b2665ba1966dbbeae666f8c9ad0 /sys/src
parentce0b77e2b9bd4669844d0356f8e49d2f4878bac8 (diff)
kernel: fix todfix() race
we have to recheck the condition under tod lock, otherwise another process can come in and updated tod.last and tod.off and once we have the lock, we would make time jump backwards.
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/9/port/tod.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/src/9/port/tod.c b/sys/src/9/port/tod.c
index 424e0f290..b88f721af 100644
--- a/sys/src/9/port/tod.c
+++ b/sys/src/9/port/tod.c
@@ -198,11 +198,13 @@ todfix(void)
uvlong x;
ticks = fastticks(nil);
+ diff = ticks - tod.last;
+ if(diff <= tod.hz)
+ return;
+ ilock(&tod);
diff = ticks - tod.last;
if(diff > tod.hz){
- ilock(&tod);
-
/* convert to epoch */
mul64fract(&x, diff, tod.multiplier);
if(x > 30000000000ULL) iprint("todfix %llud\n", x);
@@ -211,9 +213,8 @@ if(x > 30000000000ULL) iprint("todfix %llud\n", x);
/* protect against overflows */
tod.last = ticks;
tod.off = x;
-
- iunlock(&tod);
}
+ iunlock(&tod);
}
long