realtime.hpp
Go to the documentation of this file.
1 #ifndef _GRL_REALTIME_HPP_
2 #define _GRL_REALTIME_HPP_
3 
4 #ifdef __APPLE__
5 #include <mach/mach.h>
6 #include <mach/mach_time.h>
7 #include <mach/mach_init.h>
8 #include <mach/thread_policy.h>
9 //#include <mach/sched.h>
10 #include <pthread.h>
11 #include <unistd.h>
12 #include <err.h>
13 #include <sys/param.h>
14 
15 
16 static inline uint64_t
17 nanos_to_abs(uint64_t ns, uint32_t numer, uint32_t denom)
18 {
19  return (uint64_t)(ns * (((double)denom) / ((double)numer)));
20 }
21 
22 
23 /**
24  * THREAD_TIME_CONSTRAINT_POLICY:
25  *
26  * This scheduling mode is for threads which have real time
27  * constraints on their execution.
28  *
29  * Parameters:
30  *
31  * @param period: This is the nominal amount of time between separate
32  * processing arrivals, specified in absolute time units. A
33  * value of 0 indicates that there is no inherent periodicity in
34  * the computation. (nanoseconds)
35  *
36  * @param computation: This is the nominal amount of computation
37  * time needed during a separate processing arrival, specified
38  * in absolute time units. (nanoseconds)
39  *
40  * @param constraint: This is the maximum amount of real time that
41  * may elapse from the start of a separate processing arrival
42  * to the end of computation for logically correct functioning,
43  * specified in absolute time units. Must be (>= computation).
44  * Note that latency = (constraint - computation). (nanoseconds)
45  *
46  * @param preemptible: This indicates that the computation may be
47  * interrupted, subject to the constraint specified above
48  * Should almost always be false unless you really need it. (bool)
49  *
50  * @see http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/tools/tests/xnu_quick_test/sched_tests.c
51  * @see https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html
52  */
53 inline int set_realtime(int period, int computation, int constraint, bool preemptible = false) {
54 
55  struct mach_timebase_info mti;
56  struct thread_time_constraint_policy ttcpolicy;
57  kern_return_t kret;
58 
59  kret = mach_timebase_info(&mti);
60 
61  if (kret != KERN_SUCCESS) {
62  warnx("Could not get timebase info %d", kret);
63  return 0;
64  }
65 
66  thread_port_t threadport = pthread_mach_thread_np(pthread_self());
67 
68  ttcpolicy.period = nanos_to_abs(period, mti.numer, mti.denom);
69  ttcpolicy.computation = nanos_to_abs(computation, mti.numer, mti.denom); // HZ/3300;
70  ttcpolicy.constraint = nanos_to_abs(constraint, mti.numer, mti.denom); // HZ/2200;
71  ttcpolicy.preemptible = preemptible;
72 
73  if ((kret=thread_policy_set(threadport,
74  THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&ttcpolicy,
75  THREAD_TIME_CONSTRAINT_POLICY_COUNT)) != KERN_SUCCESS) {
76  fprintf(stderr, "set_realtime() failed.\n");
77  warnx("Failed to set_realtime %d", kret);
78 
79  return 0;
80  }
81  return 1;
82 }
83 #endif // __APPLE__
84 
85 
86 
87 
88 #endif