172 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright Collabora Ltd., 20214 *5 * futex cmp requeue test by André Almeida <andrealmeid@collabora.com>6 */7 8#include <pthread.h>9#include <sys/shm.h>10#include <sys/mman.h>11#include <fcntl.h>12#include "logging.h"13#include "futextest.h"14 15#define TEST_NAME "futex-wait"16#define timeout_ns 3000000017#define WAKE_WAIT_US 1000018#define SHM_PATH "futex_shm_file"19 20void *futex;21 22void usage(char *prog)23{24 printf("Usage: %s\n", prog);25 printf(" -c Use color\n");26 printf(" -h Display this help message\n");27 printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n",28 VQUIET, VCRITICAL, VINFO);29}30 31static void *waiterfn(void *arg)32{33 struct timespec to;34 unsigned int flags = 0;35 36 if (arg)37 flags = *((unsigned int *) arg);38 39 to.tv_sec = 0;40 to.tv_nsec = timeout_ns;41 42 if (futex_wait(futex, 0, &to, flags))43 printf("waiter failed errno %d\n", errno);44 45 return NULL;46}47 48int main(int argc, char *argv[])49{50 int res, ret = RET_PASS, fd, c, shm_id;51 u_int32_t f_private = 0, *shared_data;52 unsigned int flags = FUTEX_PRIVATE_FLAG;53 pthread_t waiter;54 void *shm;55 56 futex = &f_private;57 58 while ((c = getopt(argc, argv, "cht:v:")) != -1) {59 switch (c) {60 case 'c':61 log_color(1);62 break;63 case 'h':64 usage(basename(argv[0]));65 exit(0);66 case 'v':67 log_verbosity(atoi(optarg));68 break;69 default:70 usage(basename(argv[0]));71 exit(1);72 }73 }74 75 ksft_print_header();76 ksft_set_plan(3);77 ksft_print_msg("%s: Test futex_wait\n", basename(argv[0]));78 79 /* Testing a private futex */80 info("Calling private futex_wait on futex: %p\n", futex);81 if (pthread_create(&waiter, NULL, waiterfn, (void *) &flags))82 error("pthread_create failed\n", errno);83 84 usleep(WAKE_WAIT_US);85 86 info("Calling private futex_wake on futex: %p\n", futex);87 res = futex_wake(futex, 1, FUTEX_PRIVATE_FLAG);88 if (res != 1) {89 ksft_test_result_fail("futex_wake private returned: %d %s\n",90 errno, strerror(errno));91 ret = RET_FAIL;92 } else {93 ksft_test_result_pass("futex_wake private succeeds\n");94 }95 96 /* Testing an anon page shared memory */97 shm_id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666);98 if (shm_id < 0) {99 perror("shmget");100 exit(1);101 }102 103 shared_data = shmat(shm_id, NULL, 0);104 105 *shared_data = 0;106 futex = shared_data;107 108 info("Calling shared (page anon) futex_wait on futex: %p\n", futex);109 if (pthread_create(&waiter, NULL, waiterfn, NULL))110 error("pthread_create failed\n", errno);111 112 usleep(WAKE_WAIT_US);113 114 info("Calling shared (page anon) futex_wake on futex: %p\n", futex);115 res = futex_wake(futex, 1, 0);116 if (res != 1) {117 ksft_test_result_fail("futex_wake shared (page anon) returned: %d %s\n",118 errno, strerror(errno));119 ret = RET_FAIL;120 } else {121 ksft_test_result_pass("futex_wake shared (page anon) succeeds\n");122 }123 124 125 /* Testing a file backed shared memory */126 fd = open(SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);127 if (fd < 0) {128 perror("open");129 exit(1);130 }131 132 if (ftruncate(fd, sizeof(f_private))) {133 perror("ftruncate");134 exit(1);135 }136 137 shm = mmap(NULL, sizeof(f_private), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);138 if (shm == MAP_FAILED) {139 perror("mmap");140 exit(1);141 }142 143 memcpy(shm, &f_private, sizeof(f_private));144 145 futex = shm;146 147 info("Calling shared (file backed) futex_wait on futex: %p\n", futex);148 if (pthread_create(&waiter, NULL, waiterfn, NULL))149 error("pthread_create failed\n", errno);150 151 usleep(WAKE_WAIT_US);152 153 info("Calling shared (file backed) futex_wake on futex: %p\n", futex);154 res = futex_wake(shm, 1, 0);155 if (res != 1) {156 ksft_test_result_fail("futex_wake shared (file backed) returned: %d %s\n",157 errno, strerror(errno));158 ret = RET_FAIL;159 } else {160 ksft_test_result_pass("futex_wake shared (file backed) succeeds\n");161 }162 163 /* Freeing resources */164 shmdt(shared_data);165 munmap(shm, sizeof(f_private));166 remove(SHM_PATH);167 close(fd);168 169 ksft_print_cnts();170 return ret;171}172