int main(int argc, char **argv) { pthread_t thr; int ret = RET_PASS; int res; int c; while ((c = getopt(argc, argv, "chv:")) != -1) { switch (c) { case 'c': log_color(1); break; case 'h': usage(basename(argv[0])); exit(0); case 'v': log_verbosity(atoi(optarg)); break; default: usage(basename(argv[0])); exit(1); } } ksft_print_header(); ksft_set_plan(1); ksft_print_msg( "%s: Test the futex value of private file mappings in FUTEX_WAIT\n", basename(argv[0])); ret = pthread_create(&thr, NULL, thr_futex_wait, NULL); if (ret < 0) { fprintf(stderr, "pthread_create error\n"); ret = RET_ERROR; goto out; } info("wait a while\n"); usleep(WAKE_WAIT_US); val = 2; res = futex_wake(&val, 1, 0); info("futex_wake %d\n", res); if (res != 1) { fail("FUTEX_WAKE didn't find the waiting thread.\n"); ret = RET_FAIL; } info("join\n"); pthread_join(thr, NULL); out: print_result(TEST_NAME, ret); return ret; }
int main(int argc, char *argv[]) { int c, ret; while ((c = getopt(argc, argv, "bchlot:v:")) != -1) { switch (c) { case 'b': broadcast = 1; break; case 'c': log_color(1); break; case 'h': usage(basename(argv[0])); exit(0); case 'l': locked = 1; break; case 'o': owner = 1; locked = 0; break; case 't': timeout_ns = atoi(optarg); break; case 'v': log_verbosity(atoi(optarg)); break; default: usage(basename(argv[0])); exit(1); } } ksft_print_header(); ksft_print_msg("%s: Test requeue functionality\n", basename(argv[0])); ksft_print_msg( "\tArguments: broadcast=%d locked=%d owner=%d timeout=%ldns\n", broadcast, locked, owner, timeout_ns); /* * FIXME: unit_test is obsolete now that we parse options and the * various style of runs are done by run.sh - simplify the code and move * unit_test into main() */ ret = unit_test(broadcast, locked, owner, timeout_ns); print_result(TEST_NAME, ret); return ret; }
int main(int argc, char *argv[]) { futex_t f1 = FUTEX_INITIALIZER; struct timespec to; int res, ret = RET_PASS; int c; while ((c = getopt(argc, argv, "cht:v:")) != -1) { switch (c) { case 'c': log_color(1); break; case 'h': usage(basename(argv[0])); exit(0); case 't': timeout_ns = atoi(optarg); break; case 'v': log_verbosity(atoi(optarg)); break; default: usage(basename(argv[0])); exit(1); } } printf("%s: Block on a futex and wait for timeout\n", basename(argv[0])); printf("\tArguments: timeout=%ldns\n", timeout_ns); /* initialize timeout */ to.tv_sec = 0; to.tv_nsec = timeout_ns; info("Calling futex_wait on f1: %u @ %p\n", f1, &f1); res = futex_wait(&f1, f1, &to, FUTEX_PRIVATE_FLAG); if (!res || errno != ETIMEDOUT) { fail("futex_wait returned %d\n", ret < 0 ? errno : ret); ret = RET_FAIL; } print_result(ret); return ret; }
/** * Create a new context. */ XKB_EXPORT struct xkb_context * xkb_context_new(enum xkb_context_flags flags) { const char *env; struct xkb_context *ctx = calloc(1, sizeof(*ctx)); if (!ctx) return NULL; ctx->refcnt = 1; ctx->log_fn = default_log_fn; ctx->log_level = XKB_LOG_LEVEL_ERROR; ctx->log_verbosity = 0; /* Environment overwrites defaults. */ env = getenv("XKB_LOG_LEVEL"); if (env) xkb_context_set_log_level(ctx, log_level(env)); env = getenv("XKB_LOG_VERBOSITY"); if (env) xkb_context_set_log_verbosity(ctx, log_verbosity(env)); if (!(flags & XKB_CONTEXT_NO_DEFAULT_INCLUDES) && !xkb_context_include_path_append_default(ctx)) { log_err(ctx, "failed to add default include path %s\n", DFLT_XKB_CONFIG_ROOT); xkb_context_unref(ctx); return NULL; } ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES); ctx->atom_table = atom_table_new(); if (!ctx->atom_table) { xkb_context_unref(ctx); return NULL; } return ctx; }
int main(int argc, char *argv[]) { int ret = RET_PASS; pthread_t child; int c; while ((c = getopt(argc, argv, "chv:")) != -1) { switch (c) { case 'c': log_color(1); break; case 'h': usage(basename(argv[0])); exit(0); case 'v': log_verbosity(atoi(optarg)); break; default: usage(basename(argv[0])); exit(1); } } printf("%s: Detect mismatched requeue_pi operations\n", basename(argv[0])); if (pthread_create(&child, NULL, blocking_child, NULL)) { error("pthread_create\n", errno); ret = RET_ERROR; goto out; } /* Allow the child to block in the kernel. */ sleep(1); /* * The kernel should detect the waiter did not setup the * q->requeue_pi_key and return -EINVAL. If it does not, * it likely gave the lock to the child, which is now hung * in the kernel. */ ret = futex_cmp_requeue_pi(&f1, f1, &f2, 1, 0, FUTEX_PRIVATE_FLAG); if (ret < 0) { if (errno == EINVAL) { /* * The kernel correctly detected the mismatched * requeue_pi target and aborted. Wake the child with * FUTEX_WAKE. */ ret = futex_wake(&f1, 1, FUTEX_PRIVATE_FLAG); if (ret == 1) { ret = RET_PASS; } else if (ret < 0) { error("futex_wake\n", errno); ret = RET_ERROR; } else { error("futex_wake did not wake the child\n", 0); ret = RET_ERROR; } } else { error("futex_cmp_requeue_pi\n", errno); ret = RET_ERROR; } } else if (ret > 0) { fail("futex_cmp_requeue_pi failed to detect the mismatch\n"); ret = RET_FAIL; } else { error("futex_cmp_requeue_pi found no waiters\n", 0); ret = RET_ERROR; } pthread_join(child, NULL); if (!ret) ret = child_ret; out: /* If the kernel crashes, we shouldn't return at all. */ print_result(TEST_NAME, ret); return ret; }
int main(int argc, char *argv[]) { unsigned int old_val; struct sigaction sa; pthread_t waiter; int c, res, ret = RET_PASS; while ((c = getopt(argc, argv, "chv:")) != -1) { switch (c) { case 'c': log_color(1); break; case 'h': usage(basename(argv[0])); exit(0); case 'v': log_verbosity(atoi(optarg)); break; default: usage(basename(argv[0])); exit(1); } } ksft_print_header(); ksft_set_plan(1); ksft_print_msg("%s: Test signal handling during requeue_pi\n", basename(argv[0])); ksft_print_msg("\tArguments: <none>\n"); sa.sa_handler = handle_signal; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGUSR1, &sa, NULL)) { error("sigaction\n", errno); exit(1); } info("m1:f2: %x\n", f2); info("Creating waiter\n"); res = create_rt_thread(&waiter, waiterfn, NULL, SCHED_FIFO, 1); if (res) { error("Creating waiting thread failed", res); ret = RET_ERROR; goto out; } info("Calling FUTEX_LOCK_PI on f2=%x @ %p\n", f2, &f2); info("m2:f2: %x\n", f2); futex_lock_pi(&f2, 0, 0, FUTEX_PRIVATE_FLAG); info("m3:f2: %x\n", f2); while (1) { /* * signal the waiter before requeue, waiter should automatically * restart futex_wait_requeue_pi() in the kernel. Wait for the * waiter to block on f1 again. */ info("Issuing SIGUSR1 to waiter\n"); pthread_kill(waiter, SIGUSR1); usleep(DELAY_US); info("Requeueing waiter via FUTEX_CMP_REQUEUE_PI\n"); old_val = f1; res = futex_cmp_requeue_pi(&f1, old_val, &(f2), 1, 0, FUTEX_PRIVATE_FLAG); /* * If res is non-zero, we either requeued the waiter or hit an * error, break out and handle it. If it is zero, then the * signal may have hit before the the waiter was blocked on f1. * Try again. */ if (res > 0) { atomic_set(&requeued, 1); break; } else if (res < 0) { error("FUTEX_CMP_REQUEUE_PI failed\n", errno); ret = RET_ERROR; break; } } info("m4:f2: %x\n", f2); /* * Signal the waiter after requeue, waiter should return from * futex_wait_requeue_pi() with EWOULDBLOCK. Join the thread here so the * futex_unlock_pi() can't happen before the signal wakeup is detected * in the kernel. */ info("Issuing SIGUSR1 to waiter\n"); pthread_kill(waiter, SIGUSR1); info("Waiting for waiter to return\n"); pthread_join(waiter, NULL); info("Calling FUTEX_UNLOCK_PI on mutex=%x @ %p\n", f2, &f2); futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); info("m5:f2: %x\n", f2); out: if (ret == RET_PASS && waiter_ret) ret = waiter_ret; print_result(TEST_NAME, ret); return ret; }