blob: 59c66861272bc487edd1626730cdde5e665db2a1 [file] [log] [blame]
subrata_modakfd49ff62009-06-15 18:26:34 +00001/*
2 * eventfd-sem by Davide Libenzi (Simple test for eventfd sempahore)
3 * Copyright (C) 2009 Davide Libenzi
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Davide Libenzi <davidel@xmailserver.org>
20 * Reference: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=bcd0b235bf3808dec5115c381cd55568f63b85f0
21 * Reference: http://www.xmailserver.org/eventfd-sem.c
22 * eventfd: testing improved support for semaphore-like behavior in linux-2.6.30
23 *
24 */
25
26#include <sys/types.h>
27#include <sys/syscall.h>
28#include <sys/stat.h>
yaberauneyae1900272009-07-22 05:16:11 +000029#include <sys/wait.h>
subrata_modakfd49ff62009-06-15 18:26:34 +000030#include <fcntl.h>
31#include <stdlib.h>
32#include <stdio.h>
33#include <string.h>
34#include <unistd.h>
35#include <errno.h>
yaberauneyad3fe8f62009-07-22 07:54:04 +000036#include <inttypes.h>
subrata_modakfd49ff62009-06-15 18:26:34 +000037
subrata_modak6333e192009-07-06 14:49:17 +000038/* Harness Specific Include Files. */
39#include "test.h"
Andreas Bießmann3eff1992011-06-21 13:32:31 +020040#include "usctest.h"
subrata_modak6333e192009-07-06 14:49:17 +000041#include "linux_syscall_numbers.h"
42
Wanlong Gao354ebb42012-12-07 10:10:04 +080043char *TCID = "eventfd2_03"; /* test program identifier */
44int TST_TOTAL = 1; /* total number of tests in this file */
subrata_modakfd49ff62009-06-15 18:26:34 +000045
46#ifndef EFD_SEMLIKE
47#define EFD_SEMLIKE (1 << 0)
48#endif
49
yaberauneyae1900272009-07-22 05:16:11 +000050/* Dummy function as syscall from linux_syscall_numbers.h uses cleanup(). */
Wanlong Gao354ebb42012-12-07 10:10:04 +080051void cleanup()
52{
53}
subrata_modakfd49ff62009-06-15 18:26:34 +000054
Wanlong Gao354ebb42012-12-07 10:10:04 +080055static int eventfd2(int count, int flags)
56{
Jan Stancek359980f2013-02-15 10:16:05 +010057 return ltp_syscall(__NR_eventfd2, count, flags);
subrata_modakfd49ff62009-06-15 18:26:34 +000058}
59
Wanlong Gao354ebb42012-12-07 10:10:04 +080060static void xsem_wait(int fd)
61{
subrata_modakfd49ff62009-06-15 18:26:34 +000062 u_int64_t cntr;
63
64 if (read(fd, &cntr, sizeof(cntr)) != sizeof(cntr)) {
65 perror("reading eventfd");
66 exit(1);
67 }
Wanlong Gao354ebb42012-12-07 10:10:04 +080068 fprintf(stdout, "[%u] wait completed on %d: count=%" PRIu64 "\n",
subrata_modakfd49ff62009-06-15 18:26:34 +000069 getpid(), fd, cntr);
70}
71
Wanlong Gao354ebb42012-12-07 10:10:04 +080072static void xsem_post(int fd, int count)
73{
subrata_modakfd49ff62009-06-15 18:26:34 +000074 u_int64_t cntr = count;
75
76 if (write(fd, &cntr, sizeof(cntr)) != sizeof(cntr)) {
77 perror("writing eventfd");
78 exit(1);
79 }
80}
81
Wanlong Gao354ebb42012-12-07 10:10:04 +080082static void sem_player(int fd1, int fd2)
83{
subrata_modakfd49ff62009-06-15 18:26:34 +000084 fprintf(stdout, "[%u] posting 1 on %d\n", getpid(), fd1);
85 xsem_post(fd1, 1);
86
87 fprintf(stdout, "[%u] waiting on %d\n", getpid(), fd2);
88 xsem_wait(fd2);
89
90 fprintf(stdout, "[%u] posting 1 on %d\n", getpid(), fd1);
91 xsem_post(fd1, 1);
92
93 fprintf(stdout, "[%u] waiting on %d\n", getpid(), fd2);
94 xsem_wait(fd2);
95
96 fprintf(stdout, "[%u] posting 5 on %d\n", getpid(), fd1);
97 xsem_post(fd1, 5);
98
99 fprintf(stdout, "[%u] waiting 5 times on %d\n", getpid(), fd2);
100 xsem_wait(fd2);
101 xsem_wait(fd2);
102 xsem_wait(fd2);
103 xsem_wait(fd2);
104 xsem_wait(fd2);
105}
106
Wanlong Gao354ebb42012-12-07 10:10:04 +0800107static void usage(char const *prg)
108{
subrata_modakfd49ff62009-06-15 18:26:34 +0000109 fprintf(stderr, "use: %s [-h]\n", prg);
110}
111
Wanlong Gao354ebb42012-12-07 10:10:04 +0800112int main(int argc, char **argv)
113{
subrata_modakfd49ff62009-06-15 18:26:34 +0000114 int c, fd1, fd2, status;
115 pid_t cpid_poster, cpid_waiter;
116
117 while ((c = getopt(argc, argv, "h")) != -1) {
118 switch (c) {
119 default:
120 usage(argv[0]);
121 return 1;
122 }
123 }
subrata_modak6333e192009-07-06 14:49:17 +0000124 if ((tst_kvercmp(2, 6, 27)) < 0) {
125 tst_resm(TCONF,
126 "This test can only run on kernels that are 2.6.27 and higher");
127 tst_exit();
128 }
subrata_modakfd49ff62009-06-15 18:26:34 +0000129 if ((fd1 = eventfd2(0, EFD_SEMLIKE)) == -1 ||
130 (fd2 = eventfd2(0, EFD_SEMLIKE)) == -1) {
131 perror("eventfd2");
132 return 1;
133 }
134 if ((cpid_poster = fork()) == 0) {
135 sem_player(fd1, fd2);
136 exit(0);
137 }
138 if ((cpid_waiter = fork()) == 0) {
139 sem_player(fd2, fd1);
140 exit(0);
141 }
142 waitpid(cpid_poster, &status, 0);
143 waitpid(cpid_waiter, &status, 0);
144
Garrett Cooper2c282152010-12-16 00:55:50 -0800145 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700146}