DragonOS/user/apps/c_unitest/test_cross_process_futex.c

102 lines
2.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <time.h>
#include <errno.h>
#include <stdint.h>
#define FUTEX_WAIT_REQUEUE_PI 11
#define FUTEX_CMP_REQUEUE_PI 12
static long futex(uint32_t *uaddr, int futex_op, uint32_t val, const struct timespec *timeout, uint32_t *uaddr2, uint32_t val3) {
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
}
int main() {
// 创建共享内存区域
uint32_t *shared_futex = mmap(NULL, sizeof(uint32_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (shared_futex == MAP_FAILED) {
perror("mmap");
exit(1);
}
// 初始化futex
*shared_futex = 0;
printf("Parent: Setting up robust futex list...\n");
// 设置robust futex列表
struct robust_list_head {
struct robust_list *list;
long futex_offset;
struct robust_list *list_op_pending;
};
struct robust_list_head robust_head = {
.list = (struct robust_list *)shared_futex,
.futex_offset = 0,
.list_op_pending = NULL
};
// 设置当前进程的robust list
if (syscall(SYS_set_robust_list, &robust_head, sizeof(robust_head)) != 0) {
perror("set_robust_list");
exit(1);
}
pid_t pid = fork();
if (pid == 0) {
// 子进程
printf("Child: Waiting for futex...\n");
// 子进程也设置自己的robust list
struct robust_list_head child_robust_head = {
.list = (struct robust_list *)shared_futex,
.futex_offset = 0,
.list_op_pending = NULL
};
if (syscall(SYS_set_robust_list, &child_robust_head, sizeof(child_robust_head)) != 0) {
perror("child set_robust_list");
exit(1);
}
// 锁定futex
__sync_lock_test_and_set(shared_futex, getpid());
printf("Child: Acquired futex, sleeping for 1 second...\n");
sleep(1);
// 释放futex
__sync_lock_release(shared_futex);
printf("Child: Released futex, exiting...\n");
exit(0);
} else if (pid > 0) {
// 父进程
printf("Parent: Child PID = %d\n", pid);
// 等待子进程
int status;
waitpid(pid, &status, 0);
printf("Parent: Child exited, cleaning up...\n");
// 尝试访问futex这可能会触发VMA not mapped错误
printf("Parent: Futex value = %u\n", *shared_futex);
// 清理
munmap(shared_futex, sizeof(uint32_t));
printf("Parent: Done\n");
} else {
perror("fork");
exit(1);
}
return 0;
}