| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- #include <stdlib.h>
- #include <signal.h>
- #include <unistd.h>
- #include <linux/compiler.h>
- #include "../tests.h"
- typedef struct _buf {
- char data1;
- char reserved[55];
- char data2;
- } buf __attribute__((aligned(64)));
- /* volatile to try to avoid the compiler seeing reserved as unused. */
- static volatile buf workload_datasym_buf1 = {
- /* to have this in the data section */
- .reserved[0] = 1,
- };
- static volatile sig_atomic_t done;
- static void sighandler(int sig __maybe_unused)
- {
- done = 1;
- }
- static int datasym(int argc, const char **argv)
- {
- int sec = 1;
- if (argc > 0)
- sec = atoi(argv[0]);
- signal(SIGINT, sighandler);
- signal(SIGALRM, sighandler);
- alarm(sec);
- while (!done) {
- workload_datasym_buf1.data1++;
- if (workload_datasym_buf1.data1 == 123) {
- /*
- * Add some 'noise' in the loop to work around errata
- * 1694299 on Arm N1.
- *
- * Bias exists in SPE sampling which can cause the load
- * and store instructions to be skipped entirely. This
- * comes and goes randomly depending on the offset the
- * linker places the datasym loop at in the Perf binary.
- * With an extra branch in the middle of the loop that
- * isn't always taken, the instruction stream is no
- * longer a continuous repeating pattern that interacts
- * badly with the bias.
- */
- workload_datasym_buf1.data1++;
- }
- workload_datasym_buf1.data2 += workload_datasym_buf1.data1;
- }
- return 0;
- }
- DEFINE_WORKLOAD(datasym);
|