linux/tools/testing/selftests/membarrier/membarrier_test.c
<<
>>
Prefs
   1#define _GNU_SOURCE
   2#include <linux/membarrier.h>
   3#include <syscall.h>
   4#include <stdio.h>
   5#include <errno.h>
   6#include <string.h>
   7
   8#include "../kselftest.h"
   9
  10enum test_membarrier_status {
  11        TEST_MEMBARRIER_PASS = 0,
  12        TEST_MEMBARRIER_FAIL,
  13        TEST_MEMBARRIER_SKIP,
  14};
  15
  16static int sys_membarrier(int cmd, int flags)
  17{
  18        return syscall(__NR_membarrier, cmd, flags);
  19}
  20
  21static enum test_membarrier_status test_membarrier_cmd_fail(void)
  22{
  23        int cmd = -1, flags = 0;
  24
  25        if (sys_membarrier(cmd, flags) != -1) {
  26                printf("membarrier: Wrong command should fail but passed.\n");
  27                return TEST_MEMBARRIER_FAIL;
  28        }
  29        return TEST_MEMBARRIER_PASS;
  30}
  31
  32static enum test_membarrier_status test_membarrier_flags_fail(void)
  33{
  34        int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
  35
  36        if (sys_membarrier(cmd, flags) != -1) {
  37                printf("membarrier: Wrong flags should fail but passed.\n");
  38                return TEST_MEMBARRIER_FAIL;
  39        }
  40        return TEST_MEMBARRIER_PASS;
  41}
  42
  43static enum test_membarrier_status test_membarrier_success(void)
  44{
  45        int cmd = MEMBARRIER_CMD_SHARED, flags = 0;
  46
  47        if (sys_membarrier(cmd, flags) != 0) {
  48                printf("membarrier: Executing MEMBARRIER_CMD_SHARED failed. %s.\n",
  49                                strerror(errno));
  50                return TEST_MEMBARRIER_FAIL;
  51        }
  52
  53        printf("membarrier: MEMBARRIER_CMD_SHARED success.\n");
  54        return TEST_MEMBARRIER_PASS;
  55}
  56
  57static enum test_membarrier_status test_membarrier(void)
  58{
  59        enum test_membarrier_status status;
  60
  61        status = test_membarrier_cmd_fail();
  62        if (status)
  63                return status;
  64        status = test_membarrier_flags_fail();
  65        if (status)
  66                return status;
  67        status = test_membarrier_success();
  68        if (status)
  69                return status;
  70        return TEST_MEMBARRIER_PASS;
  71}
  72
  73static enum test_membarrier_status test_membarrier_query(void)
  74{
  75        int flags = 0, ret;
  76
  77        printf("membarrier MEMBARRIER_CMD_QUERY ");
  78        ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);
  79        if (ret < 0) {
  80                printf("failed. %s.\n", strerror(errno));
  81                switch (errno) {
  82                case ENOSYS:
  83                        /*
  84                         * It is valid to build a kernel with
  85                         * CONFIG_MEMBARRIER=n. However, this skips the tests.
  86                         */
  87                        return TEST_MEMBARRIER_SKIP;
  88                case EINVAL:
  89                default:
  90                        return TEST_MEMBARRIER_FAIL;
  91                }
  92        }
  93        if (!(ret & MEMBARRIER_CMD_SHARED)) {
  94                printf("command MEMBARRIER_CMD_SHARED is not supported.\n");
  95                return TEST_MEMBARRIER_FAIL;
  96        }
  97        printf("syscall available.\n");
  98        return TEST_MEMBARRIER_PASS;
  99}
 100
 101int main(int argc, char **argv)
 102{
 103        switch (test_membarrier_query()) {
 104        case TEST_MEMBARRIER_FAIL:
 105                return ksft_exit_fail();
 106        case TEST_MEMBARRIER_SKIP:
 107                return ksft_exit_skip();
 108        }
 109        switch (test_membarrier()) {
 110        case TEST_MEMBARRIER_FAIL:
 111                return ksft_exit_fail();
 112        case TEST_MEMBARRIER_SKIP:
 113                return ksft_exit_skip();
 114        }
 115
 116        printf("membarrier: tests done!\n");
 117        return ksft_exit_pass();
 118}
 119