Various userspace Linux compat hacks
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 2 Oct 2014 00:47:27 +0000 (17:47 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 2 Oct 2014 01:03:10 +0000 (18:03 -0700)
I'd like to build some of the tests for Linux without a lot of fuss.  We
can do it for pthread_test already.  Lock_test is next.

There are a variety of hacks for compatability all over the place: the
TSC stuff, a OS-independent parts of benchutil (measure.c), and more
coming soon.  If we're going to make microbenchmarks that mostly work on
both, then we should consolidate these hacks a bit.

tests/misc-compat.h
user/benchutil/include/measure.h
user/benchutil/measure.c
user/parlib/include/tsc-compat.h

index e56c76f..a0f3f4d 100644 (file)
 
 /* not quite, since akaros udelay is a busy wait */
 #define udelay(usec) usleep(usec)
+#define ndelay(nsec)                                                           \
+{                                                                              \
+       struct timespec ts = {0, 0};                                               \
+       ts.tv_nsec = (nsec);                                                       \
+       nanosleep(&ts, 0);                                                         \
+}
 
 /* not quite a normal relax, which also pauses, but this works for all archs */
 static inline void cpu_relax(void)
@@ -33,5 +39,32 @@ static inline void cpu_relax(void)
 
 #define vcore_id() (-1)
 
+#define num_vcores() ((int)sysconf(_SC_NPROCESSORS_ONLN))
+
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
+typedef void* atomic_t;
+
+static void uth_disable_notifs(void)
+{
+}
+
+static void uth_enable_notifs(void)
+{
+}
+
+#define printd(args...) {}
+
+#ifdef __x86_64__
+
+#define mb() ({ asm volatile("mfence" ::: "memory"); })
+#define cmb() ({ asm volatile("" ::: "memory"); })
+#define rmb() cmb()
+#define wmb() cmb()
+#define wrmb() mb()
+#define rwmb() cmb()
+
+#endif /* __x86_64__ */
+
 #endif /* __ros__ */
 #endif /* MISC_COMPAT_H */
index 1b427b7..0393a93 100644 (file)
@@ -7,8 +7,6 @@
  * For now, this is built into parlib.  We can pull it out in the future.  Many
  * of the larger functions are in flux (interfaces, options, etc). */
 
-#include <ros/common.h>
-
 /* Basic stats computation and printing.
  *
  * All of these expect a 2D collection of samples, where the first array is an
index 0355e87..d44ef4a 100644 (file)
@@ -7,13 +7,14 @@
  * For now, this is built into parlib.  We can pull it out in the future.  Many
  * of the larger functions are in flux. */
 
-#include <ros/common.h>
-#include <tsc-compat.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/param.h>
+#ifdef __ros__
+#include <tsc-compat.h>
 #include <measure.h>
+#endif /* __ros__ */
 
 /* Basic stats computation and printing.
  *
@@ -69,7 +70,7 @@ void compute_stats(void **data, int nr_i, int nr_j, struct sample_stats *stats)
                }
        }
        if (stats->total_samples < 2) {
-               printf("Not enough samples (%d) for avg and var\n",
+               printf("Not enough samples (%llu) for avg and var\n",
                       stats->total_samples);
                return;
        }
@@ -192,7 +193,7 @@ void compute_stats(void **data, int nr_i, int nr_j, struct sample_stats *stats)
        if (coef_var > HI_COEF_VAR)
                printf("\tHigh coeff of var with serious outliers, adjusted bins\n");
        /* numbers are overestimates by at most a lat bin */
-       printf("50/75/90/99: %d / %d / %d / %d (-<%d)\n", stats->lat_50,
+       printf("50/75/90/99: %d / %d / %d / %d (-<%ld)\n", stats->lat_50,
               stats->lat_75, stats->lat_90, stats->lat_99, lat_bin_sz);
        printf("Min / Max  : %llu / %llu\n", stats->min_time, stats->max_time);
        printf("\n");
index 3f070ff..36fee32 100644 (file)
@@ -110,6 +110,67 @@ static inline uint64_t get_tsc_overhead(void)
        return 0;
 }
 
+static inline uint64_t tsc2sec(uint64_t tsc_time)
+{
+       return tsc_time / get_tsc_freq();
+}
+
+static inline uint64_t tsc2msec(uint64_t tsc_time)
+{
+       if (mult_will_overflow_u64(tsc_time, 1000))
+               return tsc2sec(tsc_time) * 1000;
+       else
+               return (tsc_time * 1000) / get_tsc_freq();
+}
+
+static inline uint64_t tsc2usec(uint64_t tsc_time)
+{
+       if (mult_will_overflow_u64(tsc_time, 1000000))
+               return tsc2msec(tsc_time) * 1000;
+       else
+               return (tsc_time * 1000000) / get_tsc_freq();
+}
+
+static inline uint64_t tsc2nsec(uint64_t tsc_time)
+{
+       if (mult_will_overflow_u64(tsc_time, 1000000000))
+               return tsc2usec(tsc_time) * 1000;
+       else
+               return (tsc_time * 1000000000) / get_tsc_freq();
+}
+
+static inline uint64_t sec2tsc(uint64_t sec)
+{
+       if (mult_will_overflow_u64(sec, get_tsc_freq()))
+               return (uint64_t)(-1);
+       else
+               return sec * get_tsc_freq();
+}
+
+static inline uint64_t msec2tsc(uint64_t msec)
+{
+       if (mult_will_overflow_u64(msec, get_tsc_freq()))
+               return sec2tsc(msec / 1000);
+       else
+               return (msec * get_tsc_freq()) / 1000;
+}
+
+static inline uint64_t usec2tsc(uint64_t usec)
+{
+       if (mult_will_overflow_u64(usec, get_tsc_freq()))
+               return msec2tsc(usec / 1000);
+       else
+               return (usec * get_tsc_freq()) / 1000000;
+}
+
+static inline uint64_t nsec2tsc(uint64_t nsec)
+{
+       if (mult_will_overflow_u64(nsec, get_tsc_freq()))
+               return usec2tsc(nsec / 1000);
+       else
+               return (nsec * get_tsc_freq()) / 1000000000;
+}
+
 #endif /* ! _ros_ */
 
 #ifdef __cplusplus