1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (C) 2021 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> 4f08c3bdfSopenharmony_ci */ 5f08c3bdfSopenharmony_ci 6f08c3bdfSopenharmony_ci/*\ 7f08c3bdfSopenharmony_ci * [Description] 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * This test verifies futex_waitv syscall using private data. 10f08c3bdfSopenharmony_ci */ 11f08c3bdfSopenharmony_ci 12f08c3bdfSopenharmony_ci#define _GNU_SOURCE 13f08c3bdfSopenharmony_ci#include <unistd.h> 14f08c3bdfSopenharmony_ci#include <time.h> 15f08c3bdfSopenharmony_ci#include "tst_test.h" 16f08c3bdfSopenharmony_ci#include "lapi/futex.h" 17f08c3bdfSopenharmony_ci#include "lapi/syscalls.h" 18f08c3bdfSopenharmony_ci#include "futex2test.h" 19f08c3bdfSopenharmony_ci#include "futex_utils.h" 20f08c3bdfSopenharmony_ci#include "tst_safe_pthread.h" 21f08c3bdfSopenharmony_ci#include "tst_safe_clocks.h" 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_cistatic char *str_numfutex; 24f08c3bdfSopenharmony_cistatic int numfutex = 30; 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_cistatic uint32_t *futexes; 27f08c3bdfSopenharmony_cistatic struct futex_waitv *waitv; 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_cistatic void setup(void) 30f08c3bdfSopenharmony_ci{ 31f08c3bdfSopenharmony_ci struct futex_test_variants tv = futex_variant(); 32f08c3bdfSopenharmony_ci int i; 33f08c3bdfSopenharmony_ci 34f08c3bdfSopenharmony_ci tst_res(TINFO, "Testing variant: %s", tv.desc); 35f08c3bdfSopenharmony_ci futex_supported_by_kernel(tv.fntype); 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci if (tst_parse_int(str_numfutex, &numfutex, 1, FUTEX_WAITV_MAX)) 38f08c3bdfSopenharmony_ci tst_brk(TBROK, "Invalid number of futexes '%s'", str_numfutex); 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci futexes = tst_alloc(sizeof(uint32_t) * numfutex); 41f08c3bdfSopenharmony_ci memset(futexes, FUTEX_INITIALIZER, sizeof(uint32_t) * numfutex); 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_ci waitv = tst_alloc(sizeof(struct futex_waitv) * numfutex); 44f08c3bdfSopenharmony_ci memset(waitv, 0, sizeof(struct futex_waitv) * numfutex); 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci for (i = 0; i < numfutex; i++) { 47f08c3bdfSopenharmony_ci waitv[i].uaddr = (uintptr_t)&futexes[i]; 48f08c3bdfSopenharmony_ci waitv[i].flags = FUTEX_32 | FUTEX_PRIVATE_FLAG; 49f08c3bdfSopenharmony_ci waitv[i].val = 0; 50f08c3bdfSopenharmony_ci } 51f08c3bdfSopenharmony_ci} 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_cistatic void *threaded(LTP_ATTRIBUTE_UNUSED void *arg) 54f08c3bdfSopenharmony_ci{ 55f08c3bdfSopenharmony_ci struct futex_test_variants tv = futex_variant(); 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_ci TST_RETRY_FUNC(futex_wake(tv.fntype, 58f08c3bdfSopenharmony_ci (void *)(uintptr_t)waitv[numfutex - 1].uaddr, 59f08c3bdfSopenharmony_ci 1, FUTEX_PRIVATE_FLAG), futex_waked_someone); 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_ci return NULL; 62f08c3bdfSopenharmony_ci} 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_cistatic void run(void) 65f08c3bdfSopenharmony_ci{ 66f08c3bdfSopenharmony_ci struct timespec to; 67f08c3bdfSopenharmony_ci pthread_t t; 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci SAFE_PTHREAD_CREATE(&t, NULL, threaded, NULL); 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci /* setting absolute timeout for futex2 */ 72f08c3bdfSopenharmony_ci SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &to); 73f08c3bdfSopenharmony_ci to.tv_sec += 5; 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci TEST(futex_waitv(waitv, numfutex, 0, &to, CLOCK_MONOTONIC)); 76f08c3bdfSopenharmony_ci if (TST_RET < 0) { 77f08c3bdfSopenharmony_ci tst_brk(TBROK | TTERRNO, "futex_waitv returned: %ld", TST_RET); 78f08c3bdfSopenharmony_ci } else if (TST_RET != numfutex - 1) { 79f08c3bdfSopenharmony_ci tst_res(TFAIL, "futex_waitv returned: %ld, expecting %d", 80f08c3bdfSopenharmony_ci TST_RET, numfutex - 1); 81f08c3bdfSopenharmony_ci } 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_ci SAFE_PTHREAD_JOIN(t, NULL); 84f08c3bdfSopenharmony_ci tst_res(TPASS, "futex_waitv returned correctly"); 85f08c3bdfSopenharmony_ci} 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_cistatic struct tst_test test = { 88f08c3bdfSopenharmony_ci .test_all = run, 89f08c3bdfSopenharmony_ci .setup = setup, 90f08c3bdfSopenharmony_ci .min_kver = "5.16", 91f08c3bdfSopenharmony_ci .test_variants = FUTEX_VARIANTS, 92f08c3bdfSopenharmony_ci .options = 93f08c3bdfSopenharmony_ci (struct tst_option[]){ 94f08c3bdfSopenharmony_ci { "n:", &str_numfutex, "Number of futex (default 30)" }, 95f08c3bdfSopenharmony_ci {}, 96f08c3bdfSopenharmony_ci }, 97f08c3bdfSopenharmony_ci}; 98