test_cross_process_futex.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/mman.h>
  5. #include <sys/wait.h>
  6. #include <linux/futex.h>
  7. #include <sys/syscall.h>
  8. #include <time.h>
  9. #include <errno.h>
  10. #include <stdint.h>
  11. #define FUTEX_WAIT_REQUEUE_PI 11
  12. #define FUTEX_CMP_REQUEUE_PI 12
  13. static long futex(uint32_t *uaddr, int futex_op, uint32_t val, const struct timespec *timeout, uint32_t *uaddr2, uint32_t val3) {
  14. return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
  15. }
  16. int main() {
  17. // 创建共享内存区域
  18. uint32_t *shared_futex = mmap(NULL, sizeof(uint32_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  19. if (shared_futex == MAP_FAILED) {
  20. perror("mmap");
  21. exit(1);
  22. }
  23. // 初始化futex
  24. *shared_futex = 0;
  25. printf("Parent: Setting up robust futex list...\n");
  26. // 设置robust futex列表
  27. struct robust_list_head {
  28. struct robust_list *list;
  29. long futex_offset;
  30. struct robust_list *list_op_pending;
  31. };
  32. struct robust_list_head robust_head = {
  33. .list = (struct robust_list *)shared_futex,
  34. .futex_offset = 0,
  35. .list_op_pending = NULL
  36. };
  37. // 设置当前进程的robust list
  38. if (syscall(SYS_set_robust_list, &robust_head, sizeof(robust_head)) != 0) {
  39. perror("set_robust_list");
  40. exit(1);
  41. }
  42. pid_t pid = fork();
  43. if (pid == 0) {
  44. // 子进程
  45. printf("Child: Waiting for futex...\n");
  46. // 子进程也设置自己的robust list
  47. struct robust_list_head child_robust_head = {
  48. .list = (struct robust_list *)shared_futex,
  49. .futex_offset = 0,
  50. .list_op_pending = NULL
  51. };
  52. if (syscall(SYS_set_robust_list, &child_robust_head, sizeof(child_robust_head)) != 0) {
  53. perror("child set_robust_list");
  54. exit(1);
  55. }
  56. // 锁定futex
  57. __sync_lock_test_and_set(shared_futex, getpid());
  58. printf("Child: Acquired futex, sleeping for 1 second...\n");
  59. sleep(1);
  60. // 释放futex
  61. __sync_lock_release(shared_futex);
  62. printf("Child: Released futex, exiting...\n");
  63. exit(0);
  64. } else if (pid > 0) {
  65. // 父进程
  66. printf("Parent: Child PID = %d\n", pid);
  67. // 等待子进程
  68. int status;
  69. waitpid(pid, &status, 0);
  70. printf("Parent: Child exited, cleaning up...\n");
  71. // 尝试访问futex(这可能会触发VMA not mapped错误)
  72. printf("Parent: Futex value = %u\n", *shared_futex);
  73. // 清理
  74. munmap(shared_futex, sizeof(uint32_t));
  75. printf("Parent: Done\n");
  76. } else {
  77. perror("fork");
  78. exit(1);
  79. }
  80. return 0;
  81. }