futex_wait_uninitialized_heap: Detect failure, standardize logging and arguments
Rather than hang, detect the failure and report it. Standardize
arguments and use the logging facilities.
Signed-off-by: Darren Hart <dvhltc@us.ibm.com>
diff --git a/functional/futex_wait_uninitialized_heap.c b/functional/futex_wait_uninitialized_heap.c
index cd7e5f6..24bda66 100644
--- a/functional/futex_wait_uninitialized_heap.c
+++ b/functional/futex_wait_uninitialized_heap.c
@@ -32,6 +32,7 @@
*
*****************************************************************************/
+#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
@@ -46,40 +47,89 @@
#include "logging.h"
#include "futextest.h"
+#define WAIT_US 5000000
+
+static int child_blocked = 1;
+static int child_ret;
+void *buf;
+
+void usage(char *prog)
+{
+ printf("Usage: %s\n", prog);
+ printf(" -c Use color\n");
+ printf(" -h Display this help message\n");
+ printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n",
+ VQUIET, VCRITICAL, VINFO);
+}
+
+void *wait_thread(void *arg)
+{
+ int res;
+ child_ret = RET_PASS;
+ res = futex_wait(buf, 1, NULL, 0);
+ child_blocked = 0;
+
+ if (res != 0 && errno != EWOULDBLOCK) {
+ error("futex failure\n", errno);
+ child_ret = RET_ERROR;
+ }
+ pthread_exit(NULL);
+}
+
int main(int argc, char **argv)
{
+ int c, ret = RET_PASS;
long page_size;
- int res;
- void *buf;
- int ret = RET_PASS;
- int c;
+ pthread_t thr;
- while ((c = getopt(argc, argv, "c")) != -1) {
+ 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);
}
}
page_size = sysconf(_SC_PAGESIZE);
- buf = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+ buf = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
if (buf == (void *)-1) {
- perror("mmap error.\n");
+ error("mmap\n", errno);
exit(1);
}
printf("%s: Test the uninitialized futex value in FUTEX_WAIT\n",
basename(argv[0]));
- res = futex_wait(buf, 1, NULL, 0);
- if (res != 0 && errno != EWOULDBLOCK) {
- ret = RET_FAIL;
- }
- print_result(ret);
+ ret = pthread_create(&thr, NULL, wait_thread, NULL);
+ if (ret) {
+ error("pthread_create\n", errno);
+ ret = RET_ERROR;
+ goto out;
+ }
+
+ info("waiting %dus for child to return\n", WAIT_US);
+ usleep(WAIT_US);
+
+ if (child_blocked) {
+ fail("child blocked in kernel\n");
+ ret = RET_FAIL;
+ } else {
+ ret = child_ret;
+ }
+
+ out:
+ print_result(ret);
return ret;
}