1 /*
2 * Copyright 2018 Oticon A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <time.h>
7 #include <stdint.h>
8 #include "bs_tracing.h"
9 #include "bs_pc_base.h"
10 #include "bs_types.h"
11 #include "bs_handbrake_args.h"
12
13 /**
14 * This device slows down a simulation close to a given ratio of the real time
15 */
16 pb_dev_state_t pb_dev_state = {0};
17
clean_up()18 static uint8_t clean_up() {
19 bs_trace_raw(8,"Cleaning up\n");
20 pb_dev_disconnect(&pb_dev_state);
21 return 0;
22 }
23
main(int argc,char * argv[])24 int main(int argc, char *argv[]) {
25 handbrake_args_t args;
26
27 bs_trace_register_cleanup_function(clean_up);
28 bs_handbrake_argparse(argc, argv, &args);
29
30 bs_trace_raw(9,"Connecting...\n");
31 pb_dev_init_com(&pb_dev_state, args.device_nbr, args.s_id, args.p_id);
32
33 uint Stop = 0;
34 pb_wait_t wait_s;
35 struct timespec tv;
36
37 //we first wait 1us to enable all devices to do their basic initialization
38 wait_s.end = args.poke_period;
39 if ( pb_dev_request_wait_block(&pb_dev_state, &wait_s) == -1 ){
40 bs_trace_raw(3,"We have been terminated\n");
41 Stop = 1;
42 }
43
44 clock_gettime(CLOCK_MONOTONIC, &tv);
45 bs_time_t Expected_time = tv.tv_sec*1e6 + tv.tv_nsec/1000;
46
47 while ( !Stop ) {
48 wait_s.end += args.poke_period;
49 if ( pb_dev_request_wait_block(&pb_dev_state, &wait_s) == -1 ){
50 bs_trace_raw(3,"We have been terminated\n");
51 break;
52 }
53 Expected_time += (bs_time_t)(( (double)args.poke_period ) / args.real_time_ratio);
54 clock_gettime(CLOCK_MONOTONIC, &tv);
55 bs_time_t RealCurrentTime = tv.tv_sec*1e6 + tv.tv_nsec/1000;
56 int64_t diff = Expected_time - RealCurrentTime;
57
58 bs_trace_raw(7,"Diff = %li\n",diff);
59 if ( diff > 0 ){
60 struct timespec requested_time;
61 struct timespec remaining;
62
63 requested_time.tv_sec = diff / 1e6;
64 requested_time.tv_nsec = ( diff - requested_time.tv_sec*1e6 )*1e3;
65 int s = nanosleep(&requested_time, &remaining);
66 if ( s == -1 ){
67 bs_trace_warning_line("Interrupted or error\n");
68 break;
69 }
70 bs_trace_raw(6,"@%"PRItime" Stalled until real time = %"PRIuMAX"\n", wait_s.end, (uintmax_t)Expected_time);
71 }
72 }
73
74 bs_trace_raw(9,"Disconnecting...\n");
75 pb_dev_disconnect(&pb_dev_state);
76
77 bs_trace_silent_exit(0);
78 }
79