linux/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright FUJITSU LIMITED 2010
   4 * Copyright KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
   5 *
   6 *   This program is free software;  you can redistribute it and/or modify
   7 *   it under the terms of the GNU General Public License as published by
   8 *   the Free Software Foundation; either version 2 of the License, or
   9 *   (at your option) any later version.
  10 *
  11 * DESCRIPTION
  12 *      Internally, Futex has two handling mode, anon and file. The private file
  13 *      mapping is special. At first it behave as file, but after write anything
  14 *      it behave as anon. This test is intent to test such case.
  15 *
  16 * AUTHOR
  17 *      KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
  18 *
  19 * HISTORY
  20 *      2010-Jan-6: Initial version by KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
  21 *
  22 *****************************************************************************/
  23
  24#include <stdio.h>
  25#include <stdlib.h>
  26#include <syscall.h>
  27#include <unistd.h>
  28#include <errno.h>
  29#include <linux/futex.h>
  30#include <pthread.h>
  31#include <libgen.h>
  32#include <signal.h>
  33
  34#include "logging.h"
  35#include "futextest.h"
  36
  37#define TEST_NAME "futex-wait-private-mapped-file"
  38#define PAGE_SZ 4096
  39
  40char pad[PAGE_SZ] = {1};
  41futex_t val = 1;
  42char pad2[PAGE_SZ] = {1};
  43
  44#define WAKE_WAIT_US 3000000
  45struct timespec wait_timeout = { .tv_sec = 5, .tv_nsec = 0};
  46
  47void usage(char *prog)
  48{
  49        printf("Usage: %s\n", prog);
  50        printf("  -c    Use color\n");
  51        printf("  -h    Display this help message\n");
  52        printf("  -v L  Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n",
  53               VQUIET, VCRITICAL, VINFO);
  54}
  55
  56void *thr_futex_wait(void *arg)
  57{
  58        int ret;
  59
  60        info("futex wait\n");
  61        ret = futex_wait(&val, 1, &wait_timeout, 0);
  62        if (ret && errno != EWOULDBLOCK && errno != ETIMEDOUT) {
  63                error("futex error.\n", errno);
  64                print_result(TEST_NAME, RET_ERROR);
  65                exit(RET_ERROR);
  66        }
  67
  68        if (ret && errno == ETIMEDOUT)
  69                fail("waiter timedout\n");
  70
  71        info("futex_wait: ret = %d, errno = %d\n", ret, errno);
  72
  73        return NULL;
  74}
  75
  76int main(int argc, char **argv)
  77{
  78        pthread_t thr;
  79        int ret = RET_PASS;
  80        int res;
  81        int c;
  82
  83        while ((c = getopt(argc, argv, "chv:")) != -1) {
  84                switch (c) {
  85                case 'c':
  86                        log_color(1);
  87                        break;
  88                case 'h':
  89                        usage(basename(argv[0]));
  90                        exit(0);
  91                case 'v':
  92                        log_verbosity(atoi(optarg));
  93                        break;
  94                default:
  95                        usage(basename(argv[0]));
  96                        exit(1);
  97                }
  98        }
  99
 100        ksft_print_header();
 101        ksft_print_msg(
 102                "%s: Test the futex value of private file mappings in FUTEX_WAIT\n",
 103                basename(argv[0]));
 104
 105        ret = pthread_create(&thr, NULL, thr_futex_wait, NULL);
 106        if (ret < 0) {
 107                fprintf(stderr, "pthread_create error\n");
 108                ret = RET_ERROR;
 109                goto out;
 110        }
 111
 112        info("wait a while\n");
 113        usleep(WAKE_WAIT_US);
 114        val = 2;
 115        res = futex_wake(&val, 1, 0);
 116        info("futex_wake %d\n", res);
 117        if (res != 1) {
 118                fail("FUTEX_WAKE didn't find the waiting thread.\n");
 119                ret = RET_FAIL;
 120        }
 121
 122        info("join\n");
 123        pthread_join(thr, NULL);
 124
 125 out:
 126        print_result(TEST_NAME, ret);
 127        return ret;
 128}
 129