pastebin - collaborative debugging tool
rovema.kpaste.net RSS


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

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