convert from svn repository: remove tags directory
[lttv.git] / trunk / tests / kernel / test-async-tsc.c
CommitLineData
9100d218 1/* test-async-tsc.c
2 *
3 * test async tsc on AMD.
4 */
5
6
7#include <asm/atomic.h>
8#include <linux/module.h>
9#include <asm/timex.h>
10
11//LTT #define LTT_MIN_PROBE_DURATION 400
12//get_cycles
13#define LTT_MIN_PROBE_DURATION 200
14
15static atomic_long_t ltt_last_tsc = ATOMIC_LONG_INIT(0);
16
17/* When the local TSC is discovered to lag behind the highest TSC counter, we
18 * increment the TSC count of an amount that should be, ideally, lower than the
19 * execution time of this routine, in cycles : this is the granularity we look
20 * for : we must be able to order the events. */
21
22cycles_t ltt_tsc_read(void)
23{
24 cycles_t new_tsc;
25 cycles_t last_tsc;
26
27 new_tsc = get_cycles_sync();
28 if (cpu_has(&cpu_data[smp_processor_id()], X86_FEATURE_CONSTANT_TSC))
29 return new_tsc;
30
31 do {
32 last_tsc = atomic_long_read(&ltt_last_tsc);
33 if (new_tsc < last_tsc) {
34 /* last_tsc may only have incremented since last read,
35 * therefore the condition new_tsc < last_tsc still
36 * applies even if it has been updated. Therefore, we
37 * can use add_return, cheaper than cmpxchg here. */
38 new_tsc = atomic_long_add_return(LTT_MIN_PROBE_DURATION,
39 &ltt_last_tsc);
40 break;
41 }
42 /* cmpxchg will fail if ltt_last_tsc has been concurrently
43 * updated by add_return or set to a lower tsc value by a
44 * concurrent CPU at the same time. cmpxchg will succeed if
45 * the other CPUs update the ltt_last_tsc with a cmpxchg or
46 * add_return to a value higher than the new_tsc : it's ok
47 * since the current get_cycles happened before the one that
48 * causes the ltt_last_tsc to become higher than new_tsc.
49 * It also succeeds if we write to the memory location
50 * successfully without concurrent modification. */
51 } while (atomic_long_cmpxchg(&ltt_last_tsc, last_tsc, new_tsc)
52 < new_tsc);
53 return new_tsc;
54}
55
56static int __init test_init(void)
57{
58 int i;
59 cycles_t time1, time2;
60 volatile cycles_t myval;
61
62 time1 = get_cycles();
63 for (i=0; i<200; i++) {
64 //printk("time %llu\n", ltt_tsc_read());
65 //myval = ltt_tsc_read();
66 myval = get_cycles_sync();
67 }
68 time2 = get_cycles();
69 printk("timediff %llu\n", time2-time1);
70 return -EPERM;
71}
72
73static void __exit test_exit(void)
74{
75}
76
77module_init(test_init);
78module_exit(test_exit);
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mathieu Desnoyers");
82MODULE_DESCRIPTION("sync async tsc");
83
This page took 0.031549 seconds and 4 git commands to generate.