test-barrier.c revision 359017c1aec9596e9d3c4c19bd62d34a6f3366b8
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen This file is part of systemd.
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen systemd is free software; you can redistribute it and/or modify it
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen under the terms of the GNU Lesser General Public License as published by
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen (at your option) any later version.
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen systemd is distributed in the hope that it will be useful, but
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen Lesser General Public License for more details.
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen You should have received a copy of the GNU Lesser General Public License
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * IPC barrier tests
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * These tests verify the correct behavior of the IPC Barrier implementation.
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * Note that the tests use alarm-timers to verify dead-locks and timeouts. These
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * might not work on slow machines where 20ms are too short to perform specific
848d08b74eb0272774b1f8eff688d00ed9b63d9dDaniel Mack * operations (though, very unlikely). In case that turns out true, we have to
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * increase it at the slightly cost of lengthen test-duration on other machines.
848d08b74eb0272774b1f8eff688d00ed9b63d9dDaniel Mack/* 20ms to test deadlocks; All timings use multiples of this constant as
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * alarm/sleep timers. If this timeout is too small for slow machines to perform
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * the requested operations, we have to increase it. On an i7 this works fine
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * with 1ms base-time, so 20ms should be just fine for everyone. */
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen struct itimerval v = { };
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen assert_se(setitimer(ITIMER_REAL, &v, NULL) >= 0);
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen /* stupid usleep() might fail if >1000000 */
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen#define TEST_BARRIER(_FUNCTION, _CHILD_CODE, _WAIT_CHILD, _PARENT_CODE, _WAIT_PARENT) \
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen static void _FUNCTION(void) { \
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen if (pid1 == 0) { \
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen if (pid2 == 0) { \
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * Test basic sync points
370a2172ac0f455863a1ac8e7a9b0a284d810fd4Lennart Poettering * This places a barrier in both processes and waits synchronously for them.
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * The timeout makes sure the sync works as expected. The sleep_for() on one side
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * makes sure the exit of the parent does not overwrite previous barriers. Due
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * to the sleep_for(), we know that the parent already exited, thus there's a
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * pending HUP on the pipe. However, the barrier_sync() prefers reads on the
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * eventfd, thus we can safely wait on the barrier.
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * Test wait_next()
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * This places a barrier in the parent and syncs on it. The child sleeps while
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * the parent places the barrier and then waits for a barrier. The wait will
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * succeed as the child hasn't read the parent's barrier, yet. The following
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * barrier and sync synchronize the exit.
370a2172ac0f455863a1ac8e7a9b0a284d810fd4Lennart Poettering * Test wait_next() multiple times
370a2172ac0f455863a1ac8e7a9b0a284d810fd4Lennart Poettering * This places two barriers in the parent and waits for the child to exit. The
370a2172ac0f455863a1ac8e7a9b0a284d810fd4Lennart Poettering * child sleeps 20ms so both barriers _should_ be in place. It then waits for
22cedfe15fda59106b890ae2c646de96aa18a5ebDavid Herrmann * the parent to place the next barrier twice. The first call will fetch both
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * barriers and return. However, the second call will stall as the parent does
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * not place a 3rd barrier (the sleep caught two barriers). wait_next() is does
cb57dd41595adddb08095298bb1ed258c8ea4877Tom Gundersen * not look at barrier-links so this stall is expected. Thus this test times
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * Test wait_next() with local barriers
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * This is the same as test_barrier_wait_next_twice, but places local barriers
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * between both waits. This does not have any effect on the wait so it times out
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * like the other test.
d5fa81995849cb263ecfcd0aa6ab661360d9213eMartin MikkelsenTEST_BARRIER(test_barrier_wait_next_twice_local,
5ffa42cb8028833440040c2e240e0d788f11c112Tom Gundersen * Test wait_next() with sync_next()
assert_se(0);
assert_se(0);
assert_se(0);
log_open();