RobertBerger

Untitled

Jul 13th, 2020
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.69 KB | None | 0 0
  1. /*$off*/
  2. /*$4 *******************************************************************************************************************
  3. *
  4. * DESCRIPTION:  example to demonstrate how to call syscall
  5. *
  6. * AUTHOR:       robert.berger@reliableembeddedsystems.com
  7. *
  8. * FILENAME:     clock-nanoscleep.c
  9. *
  10. * REMARKS:      
  11. *
  12. * HISTORY:      001a,13 Jul 2020,robert.berger    written
  13. *
  14. * COPYRIGHT:    (C) 2020
  15. *
  16.  *********************************************************************************************************************** */
  17. /*$on*/
  18.  
  19. /*
  20. #define my_syscall(a) syscall(__NR_my_syscall, a)
  21. 407     common  clock_nanosleep_time64          sys_clock_nanosleep
  22. */
  23.  
  24. /*
  25. from kernel: arch/arm/tools/syscall.tbl
  26.  
  27. <num>   <abi>   <name>                  [<entry point>                  [<oabi compat entry point>]]
  28. #
  29. # Where abi is:
  30. #  common - for system calls shared between oabi and eabi (may have compat)
  31. #  oabi   - for oabi-only system calls (may have compat)
  32. #  eabi   - for eabi-only system calls
  33. #
  34. # For each syscall number, "common" is mutually exclusive with oabi and eabi
  35. #
  36. 407     common  clock_nanosleep_time64          sys_clock_nanosleep
  37. */
  38.  
  39.  
  40. /*
  41. from kernel: include/linux/syscalls.h
  42.  
  43. asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags,
  44.                                 const struct __kernel_timespec __user *rqtp,
  45.                                 struct __kernel_timespec __user *rmtp);
  46. */
  47.  
  48. /*
  49. from kernel config:
  50.  
  51.  config POSIX_TIMERS
  52.         bool "Posix Clocks & timers" if EXPERT
  53.         default y
  54.         help
  55.           This includes native support for POSIX timers to the kernel.
  56.           Some embedded systems have no use for them and therefore they
  57.           can be configured out to reduce the size of the kernel image.
  58.  
  59.           When this option is disabled, the following syscalls won't be
  60.           available: timer_create, timer_gettime: timer_getoverrun,
  61.           timer_settime, timer_delete, clock_adjtime, getitimer,
  62.           setitimer, alarm. Furthermore, the clock_settime, clock_gettime,
  63.           clock_getres and clock_nanosleep syscalls will be limited to
  64.           CLOCK_REALTIME, CLOCK_MONOTONIC and CLOCK_BOOTTIME only.
  65.  
  66.           If unsure say y.
  67. */
  68.  
  69. /*
  70. from glibc: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/clock_nanosleep.c
  71.  
  72. */
  73.  
  74.  
  75. /*$3 ===================================================================================================================
  76.     $C                                             Included headers
  77.  ======================================================================================================================= */
  78.  
  79. #define _GNU_SOURCE
  80.  
  81. #include <stdio.h>
  82. #include <stdlib.h>
  83. #include <errno.h>
  84. #include <sys/syscall.h>
  85. #include <unistd.h>
  86. #include <time.h>
  87.  
  88. /*$3 ===================================================================================================================
  89.     $C                                                 Constants
  90.  ======================================================================================================================= */
  91.  
  92. /*$3 ===================================================================================================================
  93.     $C                                                  Macros
  94.  ======================================================================================================================= */
  95.  
  96. /*$3 ===================================================================================================================
  97.     $C                                                   Types
  98.  ======================================================================================================================= */
  99.  
  100. #if __TIMESIZE == 64
  101. #define my__timespec64 timespec
  102. #else
  103. /* The glibc Y2038-proof struct __timespec64 structure for a time value.
  104.    To keep things Posix-ish, we keep the nanoseconds field a 32-bit
  105.    signed long, but since the Linux field is a 64-bit signed int, we
  106.    pad our tv_nsec with a 32-bit unnamed bit-field padding.
  107.  
  108.    As a general rule the Linux kernel is ignoring upper 32 bits of
  109.    tv_nsec field.  */
  110. struct my__timespec64 {
  111.     __time64_t tv_sec;  /* Seconds */
  112. #if BYTE_ORDER == BIG_ENDIAN
  113.      __int32_t:32;      /* Padding */
  114.     __int32_t tv_nsec;  /* Nanoseconds */
  115. #else
  116.     __int32_t tv_nsec;  /* Nanoseconds */
  117.      __int32_t:32;      /* Padding */
  118. #endif
  119. };
  120. #endif
  121.  
  122. /*$3 ===================================================================================================================
  123.     $C                                               Imported data
  124.  ======================================================================================================================= */
  125.  
  126. /*$3 ===================================================================================================================
  127.     $C                                               Private data
  128.  ======================================================================================================================= */
  129.  
  130. /*$3 ===================================================================================================================
  131.     $C                                                Public data
  132.  ======================================================================================================================= */
  133.  
  134. /*$3 ===================================================================================================================
  135.     $C                                      Imported function declarations
  136.  ======================================================================================================================= */
  137.  
  138. /*$3 ===================================================================================================================
  139.     $C                                       Public function declarations
  140.  ======================================================================================================================= */
  141.  
  142. /*$3 ===================================================================================================================
  143.     $C                                       Private function declarations
  144.  ======================================================================================================================= */
  145.  
  146. /*$3 ===================================================================================================================
  147.     $C                                       Private function definitions
  148.  ======================================================================================================================= */
  149.  
  150. /* Convert a known valid struct timespec into a struct __timespec64.  */
  151. static inline struct my__timespec64
  152. my_valid_timespec_to_timespec64(const struct timespec ts)
  153. {
  154.     struct my__timespec64 ts64;
  155.  
  156.     ts64.tv_sec = ts.tv_sec;
  157.     ts64.tv_nsec = ts.tv_nsec;
  158.  
  159.     return ts64;
  160. }
  161.  
  162. /*$3 ===================================================================================================================
  163.     $C                                        Public function definitions
  164.  ======================================================================================================================= */
  165.  
  166. void my_sleep_ms(int millisec)
  167. {
  168.     struct timespec res;
  169.     res.tv_sec = millisec / 1000;
  170.     res.tv_nsec = (millisec * 1000000) % 1000000000;
  171.     clock_nanosleep(CLOCK_MONOTONIC, 0, &res, NULL);
  172. }
  173.  
  174. void my_clock_nanosleep_time64(int millisec)
  175. {
  176.     long rc;
  177.     struct timespec res32;
  178.     struct my__timespec64 res64;
  179.     res32.tv_sec = millisec / 1000;
  180.     res32.tv_nsec = (millisec * 1000000) % 1000000000;
  181.  
  182.         /*
  183.            here we are set up to call
  184.        clock_nanosleep(CLOCK_MONOTONIC, 0, &res32, NULL);
  185.            but we don't call it
  186.          */
  187.        
  188.         /* instead we prepare to call clock_nanosleep_time64 */
  189.     res64 = my_valid_timespec_to_timespec64(res32);
  190.     /* call clock_nanosleep_time64 directly via syscall */
  191.     printf("--> before syscall\n");
  192.     rc = syscall(__NR_clock_nanosleep_time64,
  193.              CLOCK_MONOTONIC, 0, &res64, NULL);
  194.     printf("<-- after syscall\n");
  195.         /* check return value */
  196.     printf("\nReturned my_syscall, rc = %ld\n", rc);
  197.     if (rc < 0) {
  198.         perror("syscall returned ");
  199.     }
  200. }
  201.  
  202. int main(int argc, char *argv[])
  203. {
  204.     argc = argc;
  205.     argv = argv;
  206.  
  207.     /* call clock_nanosleep
  208.            which calls clock_nanosleep_time64 from glibc 2.30
  209.            and if that fails falls back to clock_nansleep (old syscall) instead
  210.          */
  211.  
  212.     my_sleep_ms(1);
  213.  
  214.         /* call clock_nanosleep_time64 directly via syscall
  215.            This will fail e.g. on a 4.19 kernel which does not
  216.            contain this syscall
  217.          */
  218.     my_clock_nanosleep_time64(1);
  219.  
  220.     exit(EXIT_SUCCESS);
  221. }
  222.  
  223. /* EOF */
Add Comment
Please, Sign In to add comment