datasym.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include <stdlib.h>
  2. #include <signal.h>
  3. #include <unistd.h>
  4. #include <linux/compiler.h>
  5. #include "../tests.h"
  6. typedef struct _buf {
  7. char data1;
  8. char reserved[55];
  9. char data2;
  10. } buf __attribute__((aligned(64)));
  11. /* volatile to try to avoid the compiler seeing reserved as unused. */
  12. static volatile buf workload_datasym_buf1 = {
  13. /* to have this in the data section */
  14. .reserved[0] = 1,
  15. };
  16. static volatile sig_atomic_t done;
  17. static void sighandler(int sig __maybe_unused)
  18. {
  19. done = 1;
  20. }
  21. static int datasym(int argc, const char **argv)
  22. {
  23. int sec = 1;
  24. if (argc > 0)
  25. sec = atoi(argv[0]);
  26. signal(SIGINT, sighandler);
  27. signal(SIGALRM, sighandler);
  28. alarm(sec);
  29. while (!done) {
  30. workload_datasym_buf1.data1++;
  31. if (workload_datasym_buf1.data1 == 123) {
  32. /*
  33. * Add some 'noise' in the loop to work around errata
  34. * 1694299 on Arm N1.
  35. *
  36. * Bias exists in SPE sampling which can cause the load
  37. * and store instructions to be skipped entirely. This
  38. * comes and goes randomly depending on the offset the
  39. * linker places the datasym loop at in the Perf binary.
  40. * With an extra branch in the middle of the loop that
  41. * isn't always taken, the instruction stream is no
  42. * longer a continuous repeating pattern that interacts
  43. * badly with the bias.
  44. */
  45. workload_datasym_buf1.data1++;
  46. }
  47. workload_datasym_buf1.data2 += workload_datasym_buf1.data1;
  48. }
  49. return 0;
  50. }
  51. DEFINE_WORKLOAD(datasym);