diff -Nru stress-ng-0.08.05/debian/changelog stress-ng-0.08.06/debian/changelog --- stress-ng-0.08.05/debian/changelog 2017-06-16 10:42:56.000000000 +0000 +++ stress-ng-0.08.06/debian/changelog 2017-06-21 16:33:49.000000000 +0000 @@ -1,3 +1,34 @@ +stress-ng (0.08.06-1) unstable; urgency=medium + + * Makefile: bump version + * Debian/control: update standards version to 4.0.0 + * Make test-sem-sysv.c fail for GNU/HURD + * Make test-mq-sysv.c fail for GNU/HURD + * Make test-affinity fail for GNU/HURD + * stress-cyclic: fix build issues on non-Linux platforms + * Clean up some warnings found on test config code + * Add --cyclic-method to cyclic measurements stressor + * Add build-time checks for SYSV shared memory APIs + * stress-sigsegv: add NOCLOBBER hint to fix warning with gcc 5.4.1 + * test-sem-posix: include time.h to build on BSD + * stress-sem-sysv: make semtimedop a linux only feature + * Add build-time checks for SYSV message queues + * Forgot to add in new test-mq-posix.c test source + * Add build-time checks for POSIX message queues + * Add in cyclic help options + * stress-vforkmany: add self adjusting waste memory allocation + * stress-vforkmany: make child processes larger to be more OOM'able + * stress-socket-fd: Add checks for sendmsg failures + * stress-socket-fd: send SIGALRM rathe rather than SIGKILL to child + * Add new --cyclic-dist distribution option + * stress-vforkmany: allow children to be OOM'd (LP: #1698747) + * sem-sysv: add linux checks for linux only semctl commands + * Add SYSV semaphore autodetection at build time + * job: voidify some function returns and constify len + * stress-cyclic: fix tab/spacing indentation + + -- Colin King Wed, 21 Jun 2017 17:33:49 +0100 + stress-ng (0.08.05-1) unstable; urgency=medium * test-sem-posix: don't build for FreeBSD kernels diff -Nru stress-ng-0.08.05/debian/control stress-ng-0.08.06/debian/control --- stress-ng-0.08.05/debian/control 2017-06-16 10:42:56.000000000 +0000 +++ stress-ng-0.08.06/debian/control 2017-06-21 16:33:49.000000000 +0000 @@ -2,7 +2,7 @@ Section: devel Priority: extra Maintainer: Colin King -Standards-Version: 3.9.8 +Standards-Version: 4.0.0 Build-Depends: debhelper (>= 9), zlib1g-dev, libbsd-dev, libattr1-dev, libgcrypt20-dev, libkeyutils-dev [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64], libapparmor-dev [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64], apparmor [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64], libaio-dev [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64], libcap-dev [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64], libsctp-dev [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64] Homepage: http://kernel.ubuntu.com/~cking/stress-ng diff -Nru stress-ng-0.08.05/job.c stress-ng-0.08.06/job.c --- stress-ng-0.08.05/job.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/job.c 2017-06-21 16:34:24.000000000 +0000 @@ -118,7 +118,7 @@ char *ptr = buf; int argc = 1; - memset(new_argv, 0, sizeof(new_argv)); + (void)memset(new_argv, 0, sizeof(new_argv)); new_argv[0] = argv[0]; /* remove \n */ @@ -152,7 +152,7 @@ /* managed to get any tokens? */ if (argc > 1) { - size_t len = strlen(new_argv[1]) + 3; + const size_t len = strlen(new_argv[1]) + 3; char tmp[len]; int rc; @@ -173,7 +173,7 @@ } /* prepend -- to command to make them into stress-ng options */ - snprintf(tmp, len, "--%s", new_argv[1]); + (void)snprintf(tmp, len, "--%s", new_argv[1]); new_argv[1] = tmp; parse_opts(argc, new_argv); new_argv[1] = NULL; diff -Nru stress-ng-0.08.05/Makefile stress-ng-0.08.06/Makefile --- stress-ng-0.08.05/Makefile 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/Makefile 2017-06-21 16:34:24.000000000 +0000 @@ -16,7 +16,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # -VERSION=0.08.05 +VERSION=0.08.06 # # Codename "harmful hardware harasser" # @@ -272,7 +272,8 @@ HAVE_FLOAT_DECIMAL=0 HAVE_SECCOMP_H=0 HAVE_LIB_AIO=0 HAVE_SYS_CAP_H=0 \ HAVE_VECMATH=0 HAVE_ATOMIC=0 HAVE_LIB_SCTP=0 HAVE_ASM_NOP=0 \ HAVE_ALIGNED_64K=0 HAVE_ALIGNED_64=0 HAVE_ALIGNED_128=0 \ - HAVE_AFFINITY=0 HAVE_MADVISE=0 HAVE_SEM_POSIX=0 + HAVE_AFFINITY=0 HAVE_MADVISE=0 HAVE_SEM_POSIX=0 HAVE_SEM_SYSV=0 \ + HAVE_MQ_POSIX=0 HAVE_MQ_SYSV=0 HAVE_SHM_SYSV=0 # # Load in current config; use 'make clean' to clear this @@ -490,6 +491,38 @@ endif endif +ifndef $(HAVE_SEM_SYSV) +HAVE_SEM_SYSV = $(shell $(MAKE) --no-print-directory $(HAVE_NOT) have_sem_sysv) +ifeq ($(HAVE_SEM_SYSV),1) + CONFIG_CFLAGS += -DHAVE_SEM_SYSV +$(info autoconfig: using SYSV semaphores) +endif +endif + +ifndef $(HAVE_MQ_POSIX) +HAVE_MQ_POSIX = $(shell $(MAKE) --no-print-directory $(HAVE_NOT) have_mq_posix) +ifeq ($(HAVE_MQ_POSIX),1) + CONFIG_CFLAGS += -DHAVE_MQ_POSIX +$(info autoconfig: using POSIX message queues) +endif +endif + +ifndef $(HAVE_MQ_SYSV) +HAVE_MQ_SYSV = $(shell $(MAKE) --no-print-directory $(HAVE_NOT) have_mq_sysv) +ifeq ($(HAVE_MQ_SYSV),1) + CONFIG_CFLAGS += -DHAVE_MQ_SYSV +$(info autoconfig: using SYSV message queues) +endif +endif + +ifndef $(HAVE_SHM_SYSV) +HAVE_SHM_SYSV = $(shell $(MAKE) --no-print-directory $(HAVE_NOT) have_shm_sysv) +ifeq ($(HAVE_SHM_SYSV),1) + CONFIG_CFLAGS += -DHAVE_SHM_SYSV +$(info autoconfig: using SYSV shared memory) +endif +endif + endif endif @@ -830,6 +863,57 @@ fi @rm -rf test-sem-posix +# +# check if we can build using SYSV semaphores +# +.PHONY: have_sem_sysv +have_sem_sysv: test-sem-sysv.c + @$(CC) $(CPPFLAGS) test-sem-sysv.c -o test-sem-sysv 2> /dev/null || true + @if [ -f test-sem-sysv ]; then \ + echo 1 ;\ + else \ + echo 0 ;\ + fi + @rm -rf test-sem-sysv + +# +# check if we can build using POSIX message queues +# +.PHONY: have_mq_posix +have_mq_posix: test-mq-posix.c + @$(CC) $(CPPFLAGS) test-mq-posix.c -o test-mq-posix -lrt 2> /dev/null || true + @if [ -f test-mq-posix ]; then \ + echo 1 ;\ + else \ + echo 0 ;\ + fi + @rm -rf test-mq-posix + +# +# check if we can build using SYSV message queues +# +.PHONY: have_mq_sysv_ +have_mq_sysv: test-mq-sysv.c + @$(CC) $(CPPFLAGS) test-mq-sysv.c -o test-mq-sysv 2> /dev/null || true + @if [ -f test-mq-sysv ]; then \ + echo 1 ;\ + else \ + echo 0 ;\ + fi + @rm -rf test-mq-sysv + +# +# check if we can build using SYSV shared memory +# +.PHONY: have_shm_sysv_ +have_shm_sysv: test-shm-sysv.c + @$(CC) $(CPPFLAGS) test-shm-sysv.c -o test-shm-sysv 2> /dev/null || true + @if [ -f test-shm-sysv ]; then \ + echo 1 ;\ + else \ + echo 0 ;\ + fi + @rm -rf test-shm-sysv # # extract the PER_* personality enums @@ -882,6 +966,8 @@ test-asm-nop.c test-aligned-64K.c test-aligned-64.c \ test-aligned-128.c usr.bin.pulseaudio.eg perf-event.c \ test-affinity.c test-madvise.c test-sem-posix.c \ + test-sem-sysv.c test-mq-posix.c test-mq-sysv.c \ + test-shm-sysv.c \ snapcraft smatchify.sh config TODO \ example-jobs stress-ng-$(VERSION) tar -zcf stress-ng-$(VERSION).tar.gz stress-ng-$(VERSION) diff -Nru stress-ng-0.08.05/stress-cyclic.c stress-ng-0.08.06/stress-cyclic.c --- stress-ng-0.08.05/stress-cyclic.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-cyclic.c 2017-06-21 16:34:24.000000000 +0000 @@ -53,9 +53,16 @@ double std_dev; /* standard deviation */ } rt_stats_t; +typedef int (*cyclic_func)(const args_t *args, rt_stats_t *rt_stats, uint64_t cyclic_sleep); + +typedef struct { + const char *name; + const cyclic_func func; +} stress_cyclic_method_info_t; + static const policy_t policies[] = { #if defined(SCHED_DEADLINE) - { SCHED_DEADLINE, "SCHED_DEADLINBE", "deadline" }, + { SCHED_DEADLINE, "SCHED_DEADLINE", "deadline" }, #endif #if defined(SCHED_FIFO) { SCHED_FIFO, "SCHED_FIFO", "fifo" }, @@ -67,7 +74,6 @@ static const size_t num_policies = SIZEOF_ARRAY(policies); - void stress_set_cyclic_sleep(const char *opt) { uint64_t cyclic_sleep; @@ -105,6 +111,15 @@ set_setting("cyclic-prio", TYPE_ID_INT32, &cyclic_prio); } +void stress_set_cyclic_dist(const char *opt) +{ + uint64_t cyclic_dist; + + cyclic_dist = get_uint64(opt); + check_range_bytes("cyclic-dist", cyclic_dist, 1, 10000000); + set_setting("cyclic-dist", TYPE_ID_UINT64, &cyclic_dist); +} + /* * stress_cyclic_supported() * check if we can run this as root @@ -120,8 +135,213 @@ return 0; } + +/* + * stress_cyclic_clock_nanosleep() + * measure latencies with clock_nanosleep + */ +static int stress_cyclic_clock_nanosleep( + const args_t *args, + rt_stats_t *rt_stats, + uint64_t cyclic_sleep) +{ +#if defined(__linux__) + struct timespec t1, t2, t, trem; + int ret; + + (void)args; + + t.tv_sec = cyclic_sleep / NANOSECS; + t.tv_nsec = cyclic_sleep % NANOSECS; + clock_gettime(CLOCK_REALTIME, &t1); + ret = clock_nanosleep(CLOCK_REALTIME, 0, &t, &trem); + clock_gettime(CLOCK_REALTIME, &t2); + if (ret == 0) { + int64_t delta_ns; + + delta_ns = ((t2.tv_sec - t1.tv_sec) * NANOSECS) + (t2.tv_nsec - t1.tv_nsec); + delta_ns -= cyclic_sleep; + + if (rt_stats->index < MAX_SAMPLES) + rt_stats->latencies[rt_stats->index++] = delta_ns; + + rt_stats->ns += (double)delta_ns; + } +#else + (void)args; + (void)rt_stats; + (void)cyclic_sleep; +#endif + return 0; +} + +/* + * stress_cyclic_posix_nanosleep() + * measure latencies with posix nanosleep + */ +static int stress_cyclic_posix_nanosleep( + const args_t *args, + rt_stats_t *rt_stats, + uint64_t cyclic_sleep) +{ #if defined(__linux__) + struct timespec t1, t2, t, trem; + int ret; + + (void)args; + + t.tv_sec = cyclic_sleep / NANOSECS; + t.tv_nsec = cyclic_sleep % NANOSECS; + clock_gettime(CLOCK_REALTIME, &t1); + ret = nanosleep(&t, &trem); + clock_gettime(CLOCK_REALTIME, &t2); + if (ret == 0) { + int64_t delta_ns; + + delta_ns = ((t2.tv_sec - t1.tv_sec) * NANOSECS) + (t2.tv_nsec - t1.tv_nsec); + delta_ns -= cyclic_sleep; + + if (rt_stats->index < MAX_SAMPLES) + rt_stats->latencies[rt_stats->index++] = delta_ns; + + rt_stats->ns += (double)delta_ns; + } +#else + (void)args; + (void)rt_stats; + (void)cyclic_sleep; +#endif + return 0; +} + +/* + * stress_cyclic_poll() + * measure latencies of heavy polling the clock + */ +static int stress_cyclic_poll( + const args_t *args, + rt_stats_t *rt_stats, + uint64_t cyclic_sleep) +{ +#if defined(__linux__) + struct timespec t1, t2; + + (void)args; + + /* find nearest point to clock roll over */ + clock_gettime(CLOCK_REALTIME, &t1); + for (;;) { + clock_gettime(CLOCK_REALTIME, &t2); + if ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec)) + break; + } + t1 = t2; + + for (;;) { + int64_t delta_ns; + + clock_gettime(CLOCK_REALTIME, &t2); + + delta_ns = ((t2.tv_sec - t1.tv_sec) * NANOSECS) + (t2.tv_nsec - t1.tv_nsec); + if (delta_ns >= (int64_t)cyclic_sleep) { + delta_ns -= cyclic_sleep; + + if (rt_stats->index < MAX_SAMPLES) + rt_stats->latencies[rt_stats->index++] = delta_ns; + + rt_stats->ns += (double)delta_ns; + break; + } + } +#else + (void)args; + (void)rt_stats; + (void)cyclic_sleep; +#endif + return 0; +} + + +#if defined(__linux__) +static struct timespec itimer_time; +static timer_t timerid; + +static void MLOCKED stress_cyclic_itimer_handler(int sig) +{ + (void)sig; + + clock_gettime(CLOCK_REALTIME, &itimer_time); +} +#endif + +/* + * stress_cyclic_itimer() + * measure latencies with itimers + */ +static int stress_cyclic_itimer( + const args_t *args, + rt_stats_t *rt_stats, + uint64_t cyclic_sleep) +{ +#if defined(__linux__) + struct itimerspec timer; + struct timespec t1; + int64_t delta_ns; + struct sigaction old_action; + struct sigevent sev; + int ret = -1; + + timer.it_interval.tv_sec = timer.it_value.tv_sec = cyclic_sleep / NANOSECS; + timer.it_interval.tv_nsec = timer.it_value.tv_nsec = cyclic_sleep % NANOSECS; + + if (stress_sighandler(args->name, SIGRTMIN, stress_cyclic_itimer_handler, &old_action) < 0) + return ret; + + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIGRTMIN; + sev.sigev_value.sival_ptr = &timerid; + if (timer_create(CLOCK_REALTIME, &sev, &timerid) < 0) + goto restore; + + memset(&itimer_time, 0, sizeof(itimer_time)); + clock_gettime(CLOCK_REALTIME, &t1); + if (timer_settime(timerid, 0, &timer, NULL) < 0) + goto restore; + + pause(); + if ((itimer_time.tv_sec == 0) && + (itimer_time.tv_nsec == 0)) + goto tidy; + + delta_ns = ((itimer_time.tv_sec - t1.tv_sec) * NANOSECS) + (itimer_time.tv_nsec - t1.tv_nsec); + delta_ns -= cyclic_sleep; + + if (rt_stats->index < MAX_SAMPLES) + rt_stats->latencies[rt_stats->index++] = delta_ns; + + rt_stats->ns += (double)delta_ns; + + (void)timer_delete(timerid); + + ret = 0; +tidy: + /* And cancel timer */ + (void)memset(&timer, 0, sizeof(timer)); + (void)timer_settime(timerid, 0, &timer, NULL); +restore: + stress_sigrestore(args->name, SIGRTMIN, &old_action); + return ret; +#else + (void)args; + (void)rt_stats; + (void)cyclic_sleep; + + return 0; +#endif +} + +#if defined(__linux__) static sigjmp_buf jmp_env; /* @@ -135,6 +355,7 @@ g_keep_stressing_flag = 1; siglongjmp(jmp_env, 1); } +#endif /* * stress_cyclic_cmp() @@ -206,8 +427,77 @@ } } +/* + * cyclic methods + */ +static const stress_cyclic_method_info_t cyclic_methods[] = { + { "clock_ns", stress_cyclic_clock_nanosleep }, + { "itimer", stress_cyclic_itimer }, + { "poll", stress_cyclic_poll }, + { "posix_ns", stress_cyclic_posix_nanosleep }, + { NULL, NULL } +}; + +/* + * stress_set_cyclic_method() + * set the default cyclic method + */ +int stress_set_cyclic_method(const char *name) +{ + stress_cyclic_method_info_t const *info; + + for (info = cyclic_methods; info->func; info++) { + if (!strcmp(info->name, name)) { + set_setting("cyclic-method", TYPE_ID_UINTPTR_T, &info); + return 0; + } + } + + (void)fprintf(stderr, "cyclic-method must be one of:"); + for (info = cyclic_methods; info->func; info++) { + (void)fprintf(stderr, " %s", info->name); + } + (void)fprintf(stderr, "\n"); + + return -1; +} + +#if defined(__linux__) + +/* + * stress_rt_dist() + * show real time distribution + */ +void stress_rt_dist(const char *name, rt_stats_t *rt_stats, const uint64_t cyclic_dist) +{ + size_t dist_max_size = (cyclic_dist > 0) ? (rt_stats->max_ns / cyclic_dist) + 1 : 1; + size_t dist_size = STRESS_MINIMUM(100, dist_max_size); + size_t i; + int64_t dist[dist_size]; + + if (!cyclic_dist) + return; + + memset(dist, 0, sizeof(dist)); + + for (i = 0; i < rt_stats->index; i++) { + int64_t lat = rt_stats->latencies[i] / cyclic_dist; + + if (lat < (int64_t)dist_size) + dist[lat]++; + } + + pr_inf("%s: latency distribution (%" PRIu64 " us intervals):\n", name, cyclic_dist); + pr_inf("%s: %12s %10s\n", name, "latency (us)", "frequency"); + for (i = 0; i < dist_size; i++) { + pr_inf("%s: %12" PRIu64 " %10" PRId64 "\n", + name, cyclic_dist * i, dist[i]); + } +} + int stress_cyclic(const args_t *args) { + const stress_cyclic_method_info_t *cyclic_method = &cyclic_methods[0]; const uint32_t num_instances = args->num_instances; struct sigaction old_action_xcpu; struct sched_param param = { 0 }; @@ -215,6 +505,7 @@ pid_t pid; NOCLOBBER uint64_t timeout; uint64_t cyclic_sleep = DEFAULT_DELAY_NS; + uint64_t cyclic_dist = 0; int32_t cyclic_prio = INT32_MAX; int policy; size_t cyclic_policy = 0; @@ -222,12 +513,16 @@ rt_stats_t *rt_stats; const size_t page_size = args->page_size; const size_t size = (sizeof(rt_stats_t) + page_size - 1) & (~(page_size - 1)); + cyclic_func func; timeout = g_opt_timeout; - (void)get_setting("cyclic-sleep", &cyclic_sleep); - (void)get_setting("cyclic-prio", &cyclic_prio); + (void)get_setting("cyclic-sleep", &cyclic_sleep); + (void)get_setting("cyclic-prio", &cyclic_prio); (void)get_setting("cyclic-policy", &cyclic_policy); + (void)get_setting("cyclic-dist", &cyclic_dist); + (void)get_setting("cyclic-method", &cyclic_method); + func = cyclic_method->func; policy = policies[cyclic_policy].policy; if (!args->instance) { @@ -269,6 +564,8 @@ } } + pr_dbg("%s: using method '%s'\n", args->name, cyclic_method->name); + pid = fork(); if (pid < 0) { pr_inf("%s: cannot fork, errno=%d (%s)\n", @@ -329,27 +626,7 @@ } do { - struct timespec t1, t2, t, trem; - double ns = 0.0; - - t.tv_sec = cyclic_sleep / NANOSECS; - t.tv_nsec = cyclic_sleep % NANOSECS; - clock_gettime(CLOCK_REALTIME, &t1); - ret = clock_nanosleep(CLOCK_REALTIME, 0, &t, &trem); - clock_gettime(CLOCK_REALTIME, &t2); - if (ret == 0) { - int64_t delta_ns; - - delta_ns = ((t2.tv_sec - t1.tv_sec) * NANOSECS) + (t2.tv_nsec - t1.tv_nsec); - delta_ns -= cyclic_sleep; - - ns += delta_ns; - - if (rt_stats->index < MAX_SAMPLES) - rt_stats->latencies[rt_stats->index++] = delta_ns; - - rt_stats->ns += ns; - } + func(args, rt_stats, cyclic_sleep); inc_counter(args); /* Ensure we NEVER spin forever */ @@ -409,8 +686,8 @@ rt_stats->min_ns, rt_stats->max_ns, rt_stats->std_dev); - - pr_inf("%s: latencies:\n", args->name); + + pr_inf("%s: latency percentiles:\n", args->name); for (i = 0; i < sizeof(percentiles) / sizeof(percentiles[0]); i++) { size_t j = (size_t)(((double)rt_stats->index * percentiles[i]) / 100.0); pr_inf("%s: %5.2f%%: %10" PRId64 " us\n", @@ -418,6 +695,7 @@ percentiles[i], rt_stats->latencies[j]); } + stress_rt_dist(args->name, rt_stats, cyclic_dist); } else { pr_inf("%s: %10s: no latency information available\n", args->name, diff -Nru stress-ng-0.08.05/stress-mq.c stress-ng-0.08.06/stress-mq.c --- stress-ng-0.08.05/stress-mq.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-mq.c 2017-06-21 16:34:24.000000000 +0000 @@ -24,7 +24,7 @@ */ #include "stress-ng.h" -#if defined(HAVE_LIB_RT) && defined(__linux__) +#if defined(HAVE_LIB_RT) && defined(HAVE_MQ_POSIX) #include typedef struct { diff -Nru stress-ng-0.08.05/stress-msg.c stress-ng-0.08.06/stress-msg.c --- stress-ng-0.08.05/stress-msg.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-msg.c 2017-06-21 16:34:24.000000000 +0000 @@ -24,7 +24,7 @@ */ #include "stress-ng.h" -#if !defined(__gnu_hurd__) && NEED_GLIBC(2,0,0) +#if defined(HAVE_MQ_SYSV) #include #include diff -Nru stress-ng-0.08.05/stress-ng.1 stress-ng-0.08.06/stress-ng.1 --- stress-ng-0.08.05/stress-ng.1 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-ng.1 2017-06-21 16:34:24.000000000 +0000 @@ -956,6 +956,36 @@ .B \-\-cyclic\-ops N stop after N sleeps. .TP +.B \-\-cyclic\-dist N +calculate and print a latency distribution with the interval of N nanoseconds. +This is helpful to see where the latencies are clustering. +.TP +.B \-\-cyclic\-method [ clock_ns | itimer | poll | posix_ns ] +specify the cyclic method to be used. The availble cyclic methods are as +follows: +.TS +expand; +lB2 lBw(\n[SZ]n) +l l. +Method Description +clock_ns T{ +sleep for the specified time using the clock_nanosleep(2) high +resolution nanosleep and the CLOCK_REALTIME real time clock. +T} +itimer T{ +wakeup a paused process with a CLOCK_REALTIME itimer signal. +T} +poll T{ +delay for the specified time using a poll delay loop that checks +for time changes using clock_gettime(2) on the CLOCK_REALTIME clock. +T} +posix_ns T{ +sleep for the specified time using the POSIX nanosleep(2) high +resolution nanosleep. +T} + +.TE +.TP .B \-\-cyclic\-policy [ fifo | rr ] specify the desired real time scheduling policy, ff (first-in, first-out) or rr (round robin). @@ -3119,6 +3149,15 @@ available file system space for 10 minutes. Each stressor will use 5% of the available file system space. .LP +stress\-ng \-\-cyclic 1 \-\-cyclic\-dist 2500 \-\-cyclic\-method clock_ns \-\-cyclic\-prio 100 \-\-cyclic\-sleep 10000 \-\-hdd 0 -t 1m +.IP +measures real time scheduling latencies created by the hdd stressor. This +uses the high resolution nanosecond clock to measure latencies during +sleeps of 10,000 nanoseconds. At the end of 1 minute of stressing, the +latency distribution with 2500 ns intervals will be displayed. NOTE: this +must be run with super user privileges to enable the real time scheduling +to get accurate measurements. +.LP stress\-ng \-\-cpu 8 \-\-cpu\-ops 800000 .IP runs 8 cpu stressors and stops after 800000 bogo operations. diff -Nru stress-ng-0.08.05/stress-ng.c stress-ng-0.08.06/stress-ng.c --- stress-ng-0.08.05/stress-ng.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-ng.c 2017-06-21 16:34:24.000000000 +0000 @@ -468,6 +468,8 @@ { "crypt", 1, 0, OPT_CRYPT }, { "crypt-ops", 1, 0, OPT_CRYPT_OPS }, { "cyclic", 1, 0, OPT_CYCLIC }, + { "cyclic-dist",1, 0, OPT_CYCLIC_DIST }, + { "cyclic-method",1, 0, OPT_CYCLIC_METHOD }, { "cyclic-ops",1, 0, OPT_CYCLIC_OPS }, { "cyclic-policy",1, 0, OPT_CYCLIC_POLICY }, { "cyclic-prio",1, 0, OPT_CYCLIC_PRIO }, @@ -1040,6 +1042,13 @@ { NULL, "crypt N", "start N workers performing password encryption" }, { NULL, "crypt-ops N", "stop after N bogo crypt operations" }, { NULL, "daemon N", "start N workers creating multiple daemons" }, + { NULL, "cyclic N", "start N cyclic real time benchmark stressors" }, + { NULL, "cyclic-ops N", "stop after N cyclic timing cycles" }, + { NULL, "cyclic-method M", "specify cyclic method M, default is clock_ns" }, + { NULL, "cyclic-dist N", "calculate distribution of interval N nanosecs" }, + { NULL, "cyclic-policy P", "used rr or fifo scheduling policy" }, + { NULL, "cyclic-prio N", "real time scheduling priority 1..100" }, + { NULL, "cyclic-sleep N", "sleep time of real time timer in nanosecs" }, { NULL, "daemon-ops N", "stop when N daemons have been created" }, { NULL, "dccp N", "start N workers exercising network DCCP I/O" }, { NULL, "dccp-domain D", "specify DCCP domain, default is ipv4" }, @@ -2879,6 +2888,23 @@ if (stress_set_cpu_method(optarg) < 0) exit(EXIT_FAILURE); break; + case OPT_CYCLIC_DIST: + stress_set_cyclic_dist(optarg); + break; + case OPT_CYCLIC_METHOD: + if (stress_set_cyclic_method(optarg) < 0) + exit(EXIT_FAILURE); + break; + case OPT_CYCLIC_POLICY: + if (stress_set_cyclic_policy(optarg) < 0) + exit(EXIT_FAILURE); + break; + case OPT_CYCLIC_PRIO: + stress_set_cyclic_prio(optarg); + break; + case OPT_CYCLIC_SLEEP: + stress_set_cyclic_sleep(optarg); + break; case OPT_DRY_RUN: g_opt_flags |= OPT_FLAGS_DRY_RUN; break; @@ -3111,16 +3137,6 @@ case OPT_READAHEAD_BYTES: stress_set_readahead_bytes(optarg); break; - case OPT_CYCLIC_POLICY: - if (stress_set_cyclic_policy(optarg) < 0) - exit(EXIT_FAILURE); - break; - case OPT_CYCLIC_PRIO: - stress_set_cyclic_prio(optarg); - break; - case OPT_CYCLIC_SLEEP: - stress_set_cyclic_sleep(optarg); - break; case OPT_SCHED: i32 = get_opt_sched(optarg); set_setting("sched", TYPE_ID_INT32, &i32); diff -Nru stress-ng-0.08.05/stress-ng.h stress-ng-0.08.06/stress-ng.h --- stress-ng-0.08.05/stress-ng.h 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-ng.h 2017-06-21 16:34:24.000000000 +0000 @@ -77,6 +77,10 @@ #include #include #endif +#if defined(HAVE_SEM_SYSV) +#include +#include +#endif #include #include #if defined (__GLIBC__) @@ -1452,9 +1456,11 @@ OPT_CYCLIC, OPT_CYCLIC_OPS, + OPT_CYCLIC_METHOD, OPT_CYCLIC_POLICY, OPT_CYCLIC_PRIO, OPT_CYCLIC_SLEEP, + OPT_CYCLIC_DIST, OPT_DAEMON, OPT_DAEMON_OPS, @@ -2421,9 +2427,11 @@ extern void stress_set_cpu_load(const char *opt); extern void stress_set_cpu_load_slice(const char *opt); extern int stress_set_cpu_method(const char *name); -extern int stress_set_cyclic_policy(const char *optarg); -extern void stress_set_cyclic_prio(const char *optarg); -extern void stress_set_cyclic_sleep(const char *optarg); +extern void stress_set_cyclic_dist(const char *opt); +extern int stress_set_cyclic_method(const char *opt); +extern int stress_set_cyclic_policy(const char *opt); +extern void stress_set_cyclic_prio(const char *opt); +extern void stress_set_cyclic_sleep(const char *opt); extern int stress_set_dccp_domain(const char *name); extern int stress_set_dccp_opts(const char *opt); extern void stress_set_dccp_port(const char *opt); diff -Nru stress-ng-0.08.05/stress-sem-sysv.c stress-ng-0.08.06/stress-sem-sysv.c --- stress-ng-0.08.05/stress-sem-sysv.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-sem-sysv.c 2017-06-21 16:34:24.000000000 +0000 @@ -24,10 +24,7 @@ */ #include "stress-ng.h" -#if defined(__linux__) -#include -#include - +#if defined(HAVE_SEM_SYSV) typedef union _semun { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ @@ -46,7 +43,7 @@ set_setting("sem-sysv-procs", TYPE_ID_UINT64, &semaphore_sysv_procs); } -#if defined(__linux__) +#if defined(HAVE_SEM_SYSV) /* * stress_semaphore_sysv_init() @@ -129,7 +126,11 @@ semsignal.sem_op = 1; semsignal.sem_flg = SEM_UNDO; +#if defined(__linux__) if (semtimedop(sem_id, &semwait, 1, &timeout) < 0) { +#else + if (semop(sem_id, &semwait, 1) < 0) { +#endif if (errno == EAGAIN) { pr_inf("Semaphore timed out: errno=%d (%s)\n", errno, strerror(errno)); @@ -169,7 +170,7 @@ pr_fail_dbg("semctl SEM_STAT"); } #endif -#if defined(IPC_INFO) +#if defined(IPC_INFO) && defined(__linux__) { struct seminfo si; semun_t s; @@ -179,7 +180,7 @@ pr_fail_dbg("semctl IPC_INFO"); } #endif -#if defined(SEM_INFO) +#if defined(SEM_INFO) && defined(__linux__) { struct seminfo si; semun_t s; diff -Nru stress-ng-0.08.05/stress-shm-sysv.c stress-ng-0.08.06/stress-shm-sysv.c --- stress-ng-0.08.05/stress-shm-sysv.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-shm-sysv.c 2017-06-21 16:34:24.000000000 +0000 @@ -24,6 +24,8 @@ */ #include "stress-ng.h" +#if defined(HAVE_SHM_SYSV) + #include #include @@ -62,6 +64,7 @@ */ 0 }; +#endif void stress_set_shm_sysv_bytes(const char *opt) { @@ -83,6 +86,7 @@ set_setting("shm-sysv-segs", TYPE_ID_SIZE_T, &shm_sysv_segments); } +#if defined(HAVE_SHM_SYSV) /* * stress_shm_sysv_check() * simple check if shared memory is sane @@ -472,3 +476,10 @@ } return rc; } + +#else +int stress_shm_sysv(const args_t *args) +{ + return stress_not_implemented(args); +} +#endif diff -Nru stress-ng-0.08.05/stress-sigsegv.c stress-ng-0.08.06/stress-sigsegv.c --- stress-ng-0.08.05/stress-sigsegv.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-sigsegv.c 2017-06-21 16:34:24.000000000 +0000 @@ -45,7 +45,7 @@ int stress_sigsegv(const args_t *args) { uint8_t *ptr; - int rc = EXIT_FAILURE; + NOCLOBBER int rc = EXIT_FAILURE; /* Allocate read only page */ ptr = mmap(NULL, args->page_size, PROT_READ, diff -Nru stress-ng-0.08.05/stress-socket-fd.c stress-ng-0.08.06/stress-socket-fd.c --- stress-ng-0.08.05/stress-socket-fd.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-socket-fd.c 2017-06-21 16:34:24.000000000 +0000 @@ -54,7 +54,7 @@ * stress_socket_fd_send() * send a fd (fd_send) over a socket fd */ -static inline int stress_socket_fd_send(const int fd, const int fd_send) +static inline int stress_socket_fd_sendmsg(const int fd, const int fd_send) { struct iovec iov; struct msghdr msg; @@ -250,12 +250,23 @@ size_t i; for (i = 0; i < max_fd; i++) { - int newfd = open("/dev/null", O_RDWR); + int newfd; - if (stress_socket_fd_send(sfd, newfd) < 0) - break; - if (newfd >= 0) + newfd = open("/dev/null", O_RDWR); + if (newfd >= 0) { + int ret; + + ret = stress_socket_fd_sendmsg(sfd, newfd); + if ((ret < 0) && + ((errno != EAGAIN) && (errno != EINTR) && + (errno != EWOULDBLOCK) && (errno != ECONNRESET) && + (errno != ENOMEM) && (errno != EPIPE))) { + pr_fail_dbg("sendmsg"); + (void)close(newfd); + break; + } (void)close(newfd); + } } (void)close(sfd); } @@ -271,7 +282,7 @@ } if (pid) { - (void)kill(pid, SIGKILL); + (void)kill(pid, SIGALRM); (void)waitpid(pid, &status, 0); } pr_dbg("%s: %" PRIu64 " messages sent\n", args->name, msgs); diff -Nru stress-ng-0.08.05/stress-vforkmany.c stress-ng-0.08.06/stress-vforkmany.c --- stress-ng-0.08.05/stress-vforkmany.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/stress-vforkmany.c 2017-06-21 16:34:24.000000000 +0000 @@ -25,6 +25,7 @@ #include "stress-ng.h" #define STACK_SIZE (16384) +#define WASTE_SIZE (64 * MB) /* * stress_vforkmany() @@ -70,8 +71,35 @@ munmap((void *)terminate, args->page_size); return EXIT_FAILURE; } else if (chpid == 0) { + static uint8_t *waste; + static size_t waste_size = WASTE_SIZE; + (void)setpgid(0, g_pgrp); + /* + * We want the children to be OOM'd if we + * eat up too much memory + */ + set_oom_adjustment(args->name, true); + stress_parent_died_alarm(); + + /* + * Allocate some wasted space so this child + * scores more on the OOMable score than the + * parent waiter so in theory it should be + * OOM'd before the parent. + */ + do { + waste = mmap(NULL, waste_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (waste != MAP_FAILED) + break; + + waste_size >>= 1; + } while (waste_size > 4096); + + if (waste != MAP_FAILED) + (void)memset(waste, 0, WASTE_SIZE); do { /* * Force pid to be a register, if it's @@ -82,6 +110,7 @@ */ register pid_t pid; register bool first = (instance == 0); + vfork_again: /* * SIGALRM is not inherited over vfork so @@ -104,6 +133,13 @@ if (!first) _exit(0); } else if (pid == 0) { + if (waste != MAP_FAILED) { + register size_t i; + + for (i = 0; i < WASTE_SIZE; i += 4096) + waste[i] = 0; + } + /* child, parent is blocked, spawn new child */ if (!args->max_ops || *args->counter < args->max_ops) goto vfork_again; @@ -114,6 +150,10 @@ if (!first) _exit(0); } while (keep_stressing()); + + if (waste != MAP_FAILED) + munmap(waste, WASTE_SIZE); + _exit(0); } else { /* * Parent sleeps until timeout/SIGALRM and then @@ -123,6 +163,10 @@ */ int chstatus; + (void)setpgid(chpid, g_pgrp); + g_opt_flags &= ~OPT_FLAGS_OOMABLE; + set_oom_adjustment(args->name, false); + sleep(g_opt_timeout); *terminate = true; kill(chpid, SIGALRM); diff -Nru stress-ng-0.08.05/test-affinity.c stress-ng-0.08.06/test-affinity.c --- stress-ng-0.08.05/test-affinity.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/test-affinity.c 2017-06-21 16:34:24.000000000 +0000 @@ -25,6 +25,10 @@ #define _GNU_SOURCE #include +#if defined(__gnu_hurd__) +#error sched_getaffinity and sched_setaffinity are not implemented +#endif + int main(void) { cpu_set_t mask; diff -Nru stress-ng-0.08.05/test-mq-posix.c stress-ng-0.08.06/test-mq-posix.c --- stress-ng-0.08.05/test-mq-posix.c 1970-01-01 00:00:00.000000000 +0000 +++ stress-ng-0.08.06/test-mq-posix.c 2017-06-21 16:34:24.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2013-2017 Canonical, Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * This code is a complete clean re-write of the stress tool by + * Colin Ian King and attempts to be + * backwardly compatible with the stress tool by Amos Waterland + * but has more stress tests and more + * functionality. + * + */ + +#include +#include +#include +#include +#include + + +typedef struct { + unsigned int value; +} msg_t; + +static void notify_func(union sigval s) +{ + (void)s; +} + +int main(int argc, char **argv) +{ + mqd_t mq; + msg_t msg; + struct mq_attr attr; + int ret; + struct timespec abs_timeout; + struct sigevent sigev; + char mq_name[64]; + + attr.mq_flags = 0; + attr.mq_maxmsg = 32; + attr.mq_msgsize = sizeof(msg_t); + attr.mq_curmsgs = 0; + + snprintf(mq_name, sizeof(mq_name), "/%s-%i", + argv[0], getpid()); + /* + * This is not meant to be functionally + * correct, it is just used to check we + * can build minimal POSIX message queue + * based code + */ + mq = mq_open(mq_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); + if (mq < 0) + return -1; + + (void)memset(&sigev, 0, sizeof sigev); + sigev.sigev_notify = SIGEV_THREAD; + sigev.sigev_notify_function = notify_func; + sigev.sigev_notify_attributes = NULL; + + ret = mq_notify(mq, &sigev); + (void)ret; + memset((void *)&abs_timeout, 0, sizeof(abs_timeout)); + ret = mq_timedreceive(mq, (char *)&msg, sizeof(msg), NULL, &abs_timeout); + (void)ret; + ret = mq_receive(mq, (char *)&msg, sizeof(msg), NULL); + (void)ret; + ret = mq_getattr(mq, &attr); + (void)ret; + ret = mq_timedsend(mq, (char *)&msg, sizeof(msg), 1, &abs_timeout); + (void)ret; + ret = mq_send(mq, (char *)&msg, sizeof(msg), 1); + (void)ret; + ret = mq_close(mq); + (void)ret; + ret = mq_unlink(mq_name); + (void)ret; + + return 0; +} diff -Nru stress-ng-0.08.05/test-mq-sysv.c stress-ng-0.08.06/test-mq-sysv.c --- stress-ng-0.08.05/test-mq-sysv.c 1970-01-01 00:00:00.000000000 +0000 +++ stress-ng-0.08.06/test-mq-sysv.c 2017-06-21 16:34:24.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2013-2017 Canonical, Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * This code is a complete clean re-write of the stress tool by + * Colin Ian King and attempts to be + * backwardly compatible with the stress tool by Amos Waterland + * but has more stress tests and more + * functionality. + * + */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include +#include + +#if defined(__gnu_hurd__) +#error msgsnd, msgrcv, msgget, msgctl are not implemented +#endif + +#define MAX_SIZE (8) + +typedef struct { + long mtype; + char msg[MAX_SIZE]; +} msg_t; + +int main(int argc, char **argv) +{ + int msgq_id; + msg_t msg; + int ret; + struct msqid_ds buf; +#if defined(__linux__) + struct msginfo info; +#endif + + /* + * This is not meant to be functionally + * correct, it is just used to check we + * can build minimal POSIX message queue + * based code + */ + msgq_id = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL); + if (msgq_id < 0) + return -1; + + strncpy(msg.msg, "TESTMSG", sizeof(msg.msg)); + msg.mtype = 1; + ret = msgsnd(msgq_id, &msg, sizeof(msg.msg), 0); + (void)msg; + ret = msgrcv(msgq_id, &msg, sizeof(msg.msg), 0, 0); + (void)ret; + ret = msgctl(msgq_id, IPC_STAT, &buf); + (void)ret; + ret = msgctl(msgq_id, IPC_RMID, NULL); + (void)ret; +#if defined(__linux__) + ret = msgctl(msgq_id, IPC_INFO, (struct msqid_ds *)&info); + (void)ret; + ret = msgctl(msgq_id, MSG_INFO, (struct msqid_ds *)&info); + (void)ret; +#endif + + return 0; +} diff -Nru stress-ng-0.08.05/test-sem-posix.c stress-ng-0.08.06/test-sem-posix.c --- stress-ng-0.08.05/test-sem-posix.c 2017-06-16 10:43:44.000000000 +0000 +++ stress-ng-0.08.06/test-sem-posix.c 2017-06-21 16:34:24.000000000 +0000 @@ -23,6 +23,7 @@ * */ +#include #include #if defined(__FreeBSD_kernel__) diff -Nru stress-ng-0.08.05/test-sem-sysv.c stress-ng-0.08.06/test-sem-sysv.c --- stress-ng-0.08.05/test-sem-sysv.c 1970-01-01 00:00:00.000000000 +0000 +++ stress-ng-0.08.06/test-sem-sysv.c 2017-06-21 16:34:24.000000000 +0000 @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2013-2017 Canonical, Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * This code is a complete clean re-write of the stress tool by + * Colin Ian King and attempts to be + * backwardly compatible with the stress tool by Amos Waterland + * but has more stress tests and more + * functionality. + * + */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__gnu_hurd__) +#error semop, semget and semctl are not implemented +#endif + +typedef union _semun { + int val; /* Value for SETVAL */ + struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ + unsigned short *array; /* Array for GETALL, SETALL */ + struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ +} semun_t; + +int main(void) +{ + key_t key; + int sem; + semun_t arg; + int ret; + struct sembuf semwait, semsignal; + struct timespec timeout; + + /* + * This is not meant to be functionally + * correct, it is just used to check we + * can build minimal POSIX semaphore + * based code + */ + key = (key_t)getpid(); + sem = semget(key, 1, IPC_CREAT | S_IRUSR | S_IWUSR); + arg.val = 1; + ret = semctl(sem, 0, SETVAL, arg); + (void)ret; + semwait.sem_num = 0; + semwait.sem_op = -1; + semwait.sem_flg = SEM_UNDO; + (void)clock_gettime(CLOCK_REALTIME, &timeout); + timeout.tv_sec++; +#if defined(__linux__) + ret = semtimedop(sem, &semwait, 1, &timeout); + (void)ret; +#endif + + semsignal.sem_num = 0; + semsignal.sem_op = 1; + semsignal.sem_flg = SEM_UNDO; + + ret = semop(sem, &semsignal, 1); + (void)ret; + +#if defined(IPC_STAT) + { + struct semid_ds ds; + semun_t s; + + s.buf = &ds; + ret = semctl(sem, 0, IPC_STAT, &s); + (void)ret; + } +#endif +#if defined(SEM_STAT) + { + struct semid_ds ds; + semun_t s; + + s.buf = &ds; + ret = semctl(sem, 0, SEM_STAT, &s); + (void)ret; + } +#endif +#if defined(IPC_INFO) && defined(__linux__) + { + struct seminfo si; + semun_t s; + + s.__buf = &si; + ret = semctl(sem, 0, IPC_INFO, &s); + (void)ret; + } +#endif +#if defined(SEM_INFO) && defined(__linux__) + { + struct seminfo si; + semun_t s; + + s.__buf = &si; + ret = semctl(sem, 0, SEM_INFO, &s); + (void)ret; + } +#endif +#if defined(GETVAL) + ret = semctl(sem, 0, GETVAL); + (void)ret; +#endif +#if defined(GETPID) + ret = semctl(sem, 0, GETPID); + (void)ret; +#endif +#if defined(GETNCNT) + ret = semctl(sem, 0, GETNCNT); + (void)ret; +#endif +#if defined(GEZCNT) + ret = semctl(sem, 0, GETZCNT); + (void)ret; +#endif + ret = semctl(sem, 0, IPC_RMID); + (void)ret; + + return 0; +} diff -Nru stress-ng-0.08.05/test-shm-sysv.c stress-ng-0.08.06/test-shm-sysv.c --- stress-ng-0.08.05/test-shm-sysv.c 1970-01-01 00:00:00.000000000 +0000 +++ stress-ng-0.08.06/test-shm-sysv.c 2017-06-21 16:34:24.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2013-2017 Canonical, Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * This code is a complete clean re-write of the stress tool by + * Colin Ian King and attempts to be + * backwardly compatible with the stress tool by Amos Waterland + * but has more stress tests and more + * functionality. + * + */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +int main(void) +{ + int shm_id, ret; + key_t key; + size_t sz = 64 * 1024; + char *addr; + + /* + * This is not meant to be functionally + * correct, it is just used to check we + * can build minimal POSIX semaphore + * based code + */ + key = (key_t)getpid(); + + shm_id = shmget(key, sz, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); + if (shm_id < 0) + return -1; + addr = shmat(shm_id, NULL, 0); + if (addr == (char *)-1) + goto reap; + +#if defined(IPC_STAT) + { + struct shmid_ds s; + + ret = shmctl(shm_id, IPC_INFO, (struct shmid_ds *)&s); + (void)ret; + } +#endif +#if defined(__linux__) && defined(IPC_INFO) + { + struct shminfo s; + + ret = shmctl(shm_id, IPC_INFO, (struct shmid_ds *)&s); + (void)ret; + } +#endif +#if defined(__linux__) && defined(SHM_INFO) + { + struct shm_info s; + + ret = shmctl(shm_id, SHM_INFO, (struct shmid_ds *)&s); + (void)ret; + } +#endif + + shmdt(addr); +reap: + ret = shmctl(shm_id, IPC_RMID, NULL); + (void)ret; + return 0; +}