Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 223450
b: refs/heads/master
c: b8da46d
h: refs/heads/master
v: v3
  • Loading branch information
Nicolas Pitre authored and Linus Torvalds committed Dec 20, 2010
1 parent 8fae26d commit 3a854d6
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: de5e9d58200aafea4a33abcadcd12eb69eaba5c4
refs/heads/master: b8da46d3d55807037b58f14621a0949f18053bde
10 changes: 3 additions & 7 deletions trunk/arch/mn10300/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,17 @@ unsigned long long sched_clock(void)
unsigned long long ll;
unsigned l[2];
} tsc64, result;
unsigned long tsc, tmp;
unsigned long tmp;
unsigned product[3]; /* 96-bit intermediate value */

/* cnt32_to_63() is not safe with preemption */
preempt_disable();

/* read the TSC value
*/
tsc = get_cycles();

/* expand to 64-bits.
/* expand the tsc to 64-bits.
* - sched_clock() must be called once a minute or better or the
* following will go horribly wrong - see cnt32_to_63()
*/
tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;
tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL;

preempt_enable();

Expand Down
20 changes: 19 additions & 1 deletion trunk/include/linux/cnt32_to_63.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,31 @@ union cnt32_to_63 {
*
* 2) this code must not be preempted for a duration longer than the
* 32-bit counter half period minus the longest period between two
* calls to this code.
* calls to this code;
*
* Those requirements ensure proper update to the state bit in memory.
* This is usually not a problem in practice, but if it is then a kernel
* timer should be scheduled to manage for this code to be executed often
* enough.
*
* And finally:
*
* 3) the cnt_lo argument must be seen as a globally incrementing value,
* meaning that it should be a direct reference to the counter data which
* can be evaluated according to a specific ordering within the macro,
* and not the result of a previous evaluation stored in a variable.
*
* For example, this is wrong:
*
* u32 partial = get_hw_count();
* u64 full = cnt32_to_63(partial);
* return full;
*
* This is fine:
*
* u64 full = cnt32_to_63(get_hw_count());
* return full;
*
* Note that the top bit (bit 63) in the returned value should be considered
* as garbage. It is not cleared here because callers are likely to use a
* multiplier on the returned value which can get rid of the top bit
Expand Down

0 comments on commit 3a854d6

Please sign in to comment.