thloop.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #include <pthread.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. #include <unistd.h>
  6. #include <linux/compiler.h>
  7. #include "../tests.h"
  8. static volatile sig_atomic_t done;
  9. /* We want to check this symbol in perf report */
  10. noinline void test_loop(void);
  11. static void sighandler(int sig __maybe_unused)
  12. {
  13. done = 1;
  14. }
  15. noinline void test_loop(void)
  16. {
  17. while (!done);
  18. }
  19. static void *thfunc(void *arg)
  20. {
  21. void (*loop_fn)(void) = arg;
  22. loop_fn();
  23. return NULL;
  24. }
  25. static int thloop(int argc, const char **argv)
  26. {
  27. int nt = 2, sec = 1, err = 1;
  28. pthread_t *thread_list = NULL;
  29. if (argc > 0)
  30. sec = atoi(argv[0]);
  31. if (sec <= 0) {
  32. fprintf(stderr, "Error: seconds (%d) must be >= 1\n", sec);
  33. return 1;
  34. }
  35. if (argc > 1)
  36. nt = atoi(argv[1]);
  37. if (nt <= 0) {
  38. fprintf(stderr, "Error: thread count (%d) must be >= 1\n", nt);
  39. return 1;
  40. }
  41. signal(SIGINT, sighandler);
  42. signal(SIGALRM, sighandler);
  43. thread_list = calloc(nt, sizeof(pthread_t));
  44. if (thread_list == NULL) {
  45. fprintf(stderr, "Error: malloc failed for %d threads\n", nt);
  46. goto out;
  47. }
  48. for (int i = 1; i < nt; i++) {
  49. int ret = pthread_create(&thread_list[i], NULL, thfunc, test_loop);
  50. if (ret) {
  51. fprintf(stderr, "Error: failed to create thread %d\n", i);
  52. done = 1; // Ensure started threads terminate.
  53. goto out;
  54. }
  55. }
  56. alarm(sec);
  57. test_loop();
  58. err = 0;
  59. out:
  60. for (int i = 1; i < nt; i++) {
  61. if (thread_list && thread_list[i])
  62. pthread_join(thread_list[i], /*retval=*/NULL);
  63. }
  64. free(thread_list);
  65. return err;
  66. }
  67. DEFINE_WORKLOAD(thloop);