#include <timing.h>
#include <time.h>
#include <timing_config.h>
+#include <math.h>
#define TS_SIZE 4500000
#define TB_TO_NS_SHIFT 5
-#define tb(tbu,tbl) (uint64_t)(((uint64_t)(tbu<<32))|tbl)
-#define mulhdu(a,b) ((a * b)>>64)
+//#define mulhdu(a,b) ((uint64_t)((double)a * (double)b)>>64)
#define tb_to_sched_clock(tb,shift) (tb << shift)
#ifdef CONFIG_TIMING_IPOINT_ASM
void timing_output_trace_file(void);
void timing_statistics_clock_gettime(void);
+uint64_t mulhdu(uint64_t a, uint64_t b)
+{
+ long double res;
+ res = ((long double)a*(long double)b)/pow(2.0,64.0);
+ return (uint64_t)res;
+// asm volatile (
+// " cmpwi 6,0\n"
+// " cmpwi cr1,3,0\n"
+// " mr 10,4\n"
+// " mulhwu 4,4,5\n"
+// " beq 1f\n"
+// " mulhwu 0,10,6\n"
+// " mullw 7,10,5\n"
+// " addc 7,0,7\n"
+// " addze 4,4\n"
+// "1: beqlr cr1\n" /* all done if high part of A is 0 */
+// " mr 10,3\n"
+// " mullw 9,3,5\n"
+// " mulhwu 3,3,5\n"
+// " beq 2f\n"
+// " mullw 0,10,6\n"
+// " mulhwu 8,10,6\n"
+// " addc 7,0,7\n"
+// " adde 4,4,8\n"
+// " addze 3,3\n"
+// "2: addc 4,4,9\n"
+// " addze 3,3\n"
+// " blr\n"
+// :
+// :
+// :"cr1"
+//
+// );
+}
+
+#ifdef CONFIG_TIMING_IPOINT_ASM
+uint64_t restore_tb(uint32_t tbu, uint32_t tbl)
+{
+ uint64_t tb;
+
+ tb = tbu;
+ tb <<= 32;
+ tb |= tbl;
+
+ return tb;
+}
+
+uint64_t get_boot_tb(void)
+{
+ FILE *f;
+ uint64_t boot_tb;
+
+ f = fopen("boot_tb","r");
+ if(fscanf(f, "%llu", &boot_tb)==0)
+ printf("timing: boot_tb not read successfuly!\n");
+
+ return boot_tb;
+}
+
+void print_tstamp_to_schedclock(timestamp_t *ts)
+{
+ uint64_t tb;
+ uint64_t sched_clock;
+ uint32_t sec, usec;
+
+ tb = restore_tb(ts->tbu, ts->tbl);
+// printf("tb=%llu\n",tb);
+// printf("mulhdu=%llu\n",mulhdu(tb - get_boot_tb(), tb_to_ns_scale));
+ sched_clock = (uint64_t)((long double)(mulhdu(tb - get_boot_tb(), tb_to_ns_scale))*pow(2.0,5.0));
+// printf("sched_clock=%llu\n",sched_clock);
+
+ sched_clock+=500;
+ sched_clock=sched_clock / 1000;
+
+ sec = (uint32_t) (sched_clock/1000000);
+ usec = (sched_clock % 1000000ULL);
+
+#ifdef CONFIG_TIMING_OUTPUT_SCREEN
+ printf("%d %5lu.%06lu\n", ts->id, sec, usec);
+#endif
+}
+#endif
+
timestamp_t * timestamp_handle_overflow(void)
{
static bool first_overflow = true;
system("echo 0 > /debug/tracing/tracing_enabled");
#ifdef CONFIG_TIMING_OUTPUT_FILE
system("cat /debug/tracing/trace | tee taskswitch.log");
+#endif
+#ifdef CONFIG_TIMING_OUTPUT_SCREEN
+ system("cat /debug/tracing/trace");
#endif
system("echo nop > /debug/tracing/current_tracer");
}
#ifdef CONFIG_TIMING_IPOINT_ASM
void print_ts_asm(timestamp_t *ts)
{
- printf("%d %llu\n", ts->id, tb(ts->tbu, ts->tbl));
+ printf("%d %llu\n", ts->id, restore_tb(ts->tbu, ts->tbl));
}
#endif
while(ts_iter != (timestamp_ptr+1))
{
#ifdef CONFIG_TIMING_IPOINT_ASM
- print_ts_asm(ts_iter);
+// print_ts_asm(ts_iter);
+ print_tstamp_to_schedclock(ts_iter);
#endif
ts_iter++;
i++;
while(ts_iter != (timestamp_ptr+1))
{
#ifdef CONFIG_TIMING_IPOINT_ASM
- fprintf(file, "%d %llu\n", ts_iter->id, tb(ts_iter->tbu, ts_iter->tbl));
+ fprintf(file, "%d %llu\n", ts_iter->id, restore_tb(ts_iter->tbu, ts_iter->tbl));
#endif
#ifdef CONFIG_TIMING_IPOINT_CLOCK_GETTIME
fprintf(file, "%d %.6f\n", ts_iter->id, timespec2sec(&ts_iter->ts));