pastebin - collaborative debugging tool
rovema.kpaste.net RSS


count_timer_syscalls.ksh
Posted by Anonymous on Sat 17th Sep 2022 15:25
raw | new post
view followups (newest first): count_timer_syscalls.ksh by Anonymous
modification of post by Anonymous (view diff)

  1. #!/usr/bin/ksh93
  2.  
  3. #
  4. # Count timer syscalls
  5. #
  6. # Tests whether clock_gettime() is implemented via traditional
  7. # syscalls or uses a shortcut (e.g. via shared memory/Linux VDSO)
  8. #
  9.  
  10. builtin cat
  11. builtin wc
  12. #builtin rm
  13.  
  14. set -o nounset
  15.  
  16. function enumerate_clock_sources
  17. {
  18.         typeset s
  19.         typeset dummy aname avalue
  20.         nameref ar="$1"
  21.        
  22.         s="$( clang -E -dM -m32 -include time.h - < '/dev/null' | \
  23.                 egrep \
  24.                         '#[[:space:]]*define[[:space:]]+CLOCK_.+[[:space:]]+[[:digit:]]+'
  25.                 )"
  26.        
  27.         while read dummy aname avalue ; do
  28.                 if [[ \
  29.                         "${aname}" != ~(El)CLOCK_ || \
  30.                         "${avalue}" != ~(Elr)[[:digit:]]+ ]] ; then
  31.                         continue
  32.                 fi
  33.                 integer ar["$aname"].value
  34.                 ar["$aname"].name="${aname}"
  35.                 ar["$aname"].value="${avalue}"
  36.         done <<<"$s"
  37.        
  38.         return 0
  39. }
  40.  
  41. function generate_test_code
  42. {
  43.         nameref ar="$1"
  44.  
  45.         set -o errexit
  46.        
  47.         printf $"## Generating test code...\n"
  48.  
  49.         rm -f \
  50.                 'generated_count_timer_syscalls.c' \
  51.                 'generated_count_timer_syscalls'
  52.  
  53.         {
  54.                 cat <<EOF
  55.  
  56. /*
  57.  * count_timer_syscalls.c - runs timer NUM_TESTRUNS times,
  58.  * strace can then be used to count syscalls
  59.  *
  60.  * Compile with:
  61.  * $ clang -g -Wall -Wextra count_timer_syscalls.c
  62.  *
  63.  */
  64.  
  65. #include <sys/types.h>
  66. #include <sys/stat.h>
  67. #include <fcntl.h>
  68. #include <unistd.h>
  69. #include <time.h>
  70. #include <sched.h>
  71. #include <stdlib.h>
  72. #include <stdint.h>
  73. #include <stdio.h>
  74. #include <string.h>
  75. #include <errno.h>
  76.  
  77.  
  78. #ifndef CLOCK_INVALID
  79. #define CLOCK_INVALID -1
  80. #endif
  81.  
  82. #define NSEC_PER_SEC (1000000000LL)
  83.  
  84. #define NUM_TESTRUNS (32000UL)
  85.  
  86.  
  87. static
  88. clockid_t get_clockid(int fd)
  89. {
  90.         const int CLOCKFD = 3;
  91.  
  92.         return (((unsigned int) ~fd) << 3) | CLOCKFD;
  93. }
  94.  
  95.  
  96. static
  97. void test_loop_on_clock(clockid_t clkid, unsigned long num_cycles)
  98. {
  99.         struct timespec ts;
  100.         unsigned long cycles;
  101.  
  102.         for(cycles = 0UL ; cycles < num_cycles ; cycles++)
  103.         {
  104.                 (void)clock_gettime(clkid, &ts);
  105.                 (void)ts;
  106.         }
  107. }
  108.  
  109.  
  110. int main(int ac, char *av[])
  111. {
  112.         const char *clockname = av[1];
  113.  
  114.         (void)puts("# start.");
  115.        
  116.         if ((ac != 2) || (!clockname)) {
  117.                 (void)fprintf(stderr, "%s: Missing clockname argument\n", av[0]);
  118.                 return EXIT_FAILURE;
  119.         }
  120.        
  121.         if (!strcmp(clockname, "nic")) {
  122.                 int fd;
  123.                 clockid_t clkid;
  124.                 const char *devicename = "/dev/ptp0";
  125.  
  126.                 fd = open(devicename, O_RDWR);
  127.                 if (fd < 0) {
  128.                         (void)fprintf(stderr, "opening %s: %s\n", devicename,
  129.                                 strerror(errno));
  130.                         return(EXIT_FAILURE);
  131.                 }
  132.  
  133.                 clkid = get_clockid(fd);
  134.                 if (CLOCK_INVALID == clkid) {
  135.                         (void)fprintf(stderr, "failed to read clock id\n");
  136.                         return(EXIT_FAILURE);
  137.                 }
  138.  
  139.                 (void)printf("## test run using nic clock\n");
  140.                 test_loop_on_clock(clkid, NUM_TESTRUNS);
  141.  
  142.                 (void)close(fd);
  143. EOF
  144.  
  145.                 typeset i
  146.                 for i in "${!ar[@]}" ; do
  147.                         typeset name="${ar[$i].name}"
  148.                         printf '\t} else if (!strcmp(clockname, "%s")) {\n' "$name"
  149.                         printf '\t\t(void)printf("## test run using %s\\n");\n' "$name"
  150.                         printf '\n'
  151.                         printf '\t\ttest_loop_on_clock(%s, NUM_TESTRUNS);\n' "$name"
  152.                 done
  153.  
  154.                 cat <<EOF
  155.         } else {
  156.                 (void)fprintf(stderr, "%s: Unknown clockname argument %s\n",
  157.                         av[0], clockname);
  158.                 return EXIT_FAILURE;
  159.         }
  160.  
  161.         (void)puts("# end.");
  162.  
  163.         return(EXIT_SUCCESS);
  164. }
  165. EOF
  166.         } >"generated_count_timer_syscalls.c"
  167.        
  168.         return 0
  169. }
  170.  
  171. function compile_test_code
  172. {
  173.         set -o errexit
  174.  
  175.         printf $"## Compiling test code...\n"
  176.        
  177.         clang -m32 -g -Wall -Wextra \
  178.                 -o generated_count_timer_syscalls \
  179.                 generated_count_timer_syscalls.c
  180.        
  181.         return 0
  182. }
  183.  
  184. function run_tests
  185. {
  186.         nameref ar="$1"
  187.         compound cmd
  188.         typeset cmd.output
  189.         integer cmd.exit_code
  190.         typeset i
  191.  
  192.         printf $"## Running tests...\n"
  193.        
  194.         for i in "${!ar[@]}" ; do
  195.                 nameref n=ar["$i"]
  196.                
  197.                 printf $"Probing %q...\n" "${n.name}"
  198.                 cmd.output="${ strace ./generated_count_timer_syscalls "${n.name}" 2>&1 ; cmd.exit_code="$?" ; }"
  199.                
  200.                 integer n.num_syscalls_clock_gettime="${ egrep 'clock_gettime' <<<"${cmd.output}" | wc -l ;}"
  201.                 integer n.num_syscalls_total="${ wc -l <<<"${cmd.output}" ; }"
  202.                 integer n.exit_code=${cmd.exit_code}
  203.         done
  204. }
  205.  
  206. function print_results
  207. {
  208.         nameref c=$1
  209.         printf $"## Raw test results:\n"
  210.         print -v c
  211.        
  212.         printf $"## Summary of test results for %q:\n" "${c.uname}"
  213.         nameref ar="c.clock_names"
  214.         for i in "${!ar[@]}" ; do
  215.                 nameref n=ar["$i"]
  216.                
  217.                 printf $"Clock name %-20s \t" ${n.name}
  218.                 if (( (n.exit_code != 0) || (n.num_syscalls_total < 30) )) ; then
  219.                         printf $"TEST FAILED\n"
  220.                 elif (( n.num_syscalls_clock_gettime >= 32000 )) ; then
  221.                         printf $"uses traditional syscalls\n"
  222.                 elif (( n.num_syscalls_clock_gettime <= 1 )) ; then
  223.                         printf $"uses shortcut\n"
  224.                 else
  225.                         printf $"Data inconclusive\n"
  226.                 fi
  227.         done   
  228.         return 0
  229. }
  230.  
  231. function main
  232. {
  233.         compound c
  234.         compound -A c.clock_names
  235.        
  236.         typeset c.uname="$(uname -a)"
  237.         typeset c.hostname="$(hostname)"
  238.  
  239.         if ! enumerate_clock_sources c.clock_names ; then
  240.                 print -u2 -f $"%s: Could not enumerate clock names.\n" "$1"
  241.                 return 1
  242.         fi
  243.  
  244.         if ! generate_test_code c.clock_names ; then
  245.                 print -u2 -f $"%s: Could not generate test code.\n" "$1"
  246.                 return 1
  247.         fi
  248.  
  249.         if ! compile_test_code ; then
  250.                 print -u2 -f $"%s: Could not compile test code.\n" "$1"
  251.                 return 1
  252.         fi
  253.  
  254.         run_tests c.clock_names
  255.  
  256.         print_results c
  257.        
  258.         print $"## Done."
  259.         return 0
  260. }
  261.  
  262. main "$@"
  263. # EOF.

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at