ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
extra_mac.c
Go to the documentation of this file.
1 #include "includes.h"
2 #ifdef OS_MAC
3 
4 #include <mach/mach_time.h>
5 
6 // ¯\_(ツ)_/¯
7 
8 void *memrchr(const void *s, int c, size_t n){
9  const char* cs = s;
10  for(size_t i = n; i > 0; i--){
11  if(cs[i - 1] == c)
12  return (void*)(cs + i - 1);
13  }
14  return 0;
15 }
16 
17 // Mach timebase scale
18 double getfactor(){
19  static unsigned long factor = 0;
20  if(factor)
21  return factor;
22  mach_timebase_info_data_t info;
23  mach_timebase_info(&info);
24  return factor = (double)info.numer / (double)info.denom;
25 }
26 
27 int clock_gettime(clockid_t clk_id, struct timespec *tp){
28  if(clk_id != CLOCK_MONOTONIC){
29  errno = EINVAL;
30  return -1;
31  }
32  unsigned long factor = getfactor();
33  unsigned long nsec = mach_absolute_time() * factor;
34  tp->tv_sec = nsec / 1000000000;
35  tp->tv_nsec = nsec % 1000000000;
36  return 0;
37 }
38 
39 int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp){
40  if(clock_id != CLOCK_MONOTONIC)
41  return EINVAL;
42  if(flags == TIMER_ABSTIME){
43  // Absolute time
44  // Determine the amount of time left to wait
45  struct timespec curtime, realtime;
46  clock_gettime(clock_id, &curtime);
47  if(timespec_ge(curtime, *rqtp))
48  // Time already passed
49  return 0;
50  realtime.tv_sec = rqtp->tv_sec - curtime.tv_sec;
51  realtime.tv_nsec = rqtp->tv_nsec - curtime.tv_nsec;
52  if(realtime.tv_nsec < 0){
53  // Borrow on underflow
54  realtime.tv_sec--;
55  realtime.tv_nsec += 1000000000;
56  }
57  int res = nanosleep(&realtime, 0);
58  if(!res)
59  return 0;
60  return errno;
61  }
62  // Relative time
63  int res = nanosleep(rqtp, rmtp);
64  if(!res)
65  return 0;
66  return errno;
67 }
68 
69 #endif
#define timespec_ge(left, right)
Definition: includes.h:61