We do this here because otherwise user space would do it on
its own in a likely inferior way (no access to jiffies).
If you don't like it pass NULL. */
- if (tcache && tcache->t0 == (j = __jiffies)) {
- p = tcache->t1;
+ if (tcache && tcache->blob[0] == (j = __jiffies)) {
+ p = tcache->blob[1];
} else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
/* Load per CPU data from RDTSCP */
rdtscp(dummy, dummy, p);
asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
}
if (tcache) {
- tcache->t0 = j;
- tcache->t1 = p;
+ tcache->blob[0] = j;
+ tcache->blob[1] = p;
}
if (cpu)
*cpu = p & 0xfff;
#ifndef _LINUX_GETCPU_H
#define _LINUX_GETCPU_H 1
-/* Cache for getcpu() to speed it up. Results might be upto a jiffie
+/* Cache for getcpu() to speed it up. Results might be a short time
out of date, but will be faster.
+
User programs should not refer to the contents of this structure.
- It is only a cache for vgetcpu(). It might change in future kernels.
+ I repeat they should not refer to it. If they do they will break
+ in future kernels.
+
+ It is only a private cache for vgetcpu(). It will change in future kernels.
The user program must store this information per thread (__thread)
If you want 100% accurate information pass NULL instead. */
struct getcpu_cache {
- unsigned long t0;
- unsigned long t1;
- unsigned long res[4];
+ unsigned long blob[128 / sizeof(long)];
};
#endif
* padding
*/
unsigned long t0, t1;
- get_user(t0, &cache->t0);
- get_user(t1, &cache->t1);
+ get_user(t0, &cache->blob[0]);
+ get_user(t1, &cache->blob[1]);
t0++;
t1++;
- put_user(t0, &cache->t0);
- put_user(t1, &cache->t1);
+ put_user(t0, &cache->blob[0]);
+ put_user(t1, &cache->blob[1]);
}
return err ? -EFAULT : 0;
}