atomic_wait_notify.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (C) 2023 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include <stdio.h>
  6. #include <pthread.h>
  7. #include <stdbool.h>
  8. #define MAX_NUM_THREADS 4
  9. #define NUM_ITER 100000
  10. int g_val;
  11. int my_mutex;
  12. int
  13. try_lock()
  14. {
  15. return __atomic_compare_exchange(&my_mutex, &(int){ 0 }, &(int){ 1 }, false,
  16. __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
  17. }
  18. void
  19. lock_acquire()
  20. {
  21. while (!try_lock()) {
  22. // expected value (1 => locked)
  23. __builtin_wasm_memory_atomic_wait32(&my_mutex, 1, -1);
  24. }
  25. }
  26. void
  27. lock_release()
  28. {
  29. // unlock the mutex
  30. __atomic_store(&my_mutex, &(int){ 0 }, __ATOMIC_SEQ_CST);
  31. // notify 1 waiter
  32. __builtin_wasm_memory_atomic_notify(&my_mutex, 1);
  33. }
  34. static void *
  35. thread(void *arg)
  36. {
  37. for (int i = 0; i < NUM_ITER; i++) {
  38. lock_acquire();
  39. g_val++;
  40. lock_release();
  41. }
  42. return NULL;
  43. }
  44. int
  45. main()
  46. {
  47. pthread_t tids[MAX_NUM_THREADS];
  48. for (int i = 0; i < MAX_NUM_THREADS; i++) {
  49. if (pthread_create(&tids[i], NULL, thread, NULL) != 0) {
  50. printf("Thread creation failed\n");
  51. }
  52. }
  53. for (int i = 0; i < MAX_NUM_THREADS; i++) {
  54. if (pthread_join(tids[i], NULL) != 0) {
  55. printf("Thread join failed\n");
  56. }
  57. }
  58. printf("Value of counter after add update: %d (expected=%d)\n", g_val,
  59. MAX_NUM_THREADS * NUM_ITER);
  60. if (g_val != MAX_NUM_THREADS * NUM_ITER) {
  61. __builtin_trap();
  62. }
  63. return 0;
  64. }