1 /*
2  * Copyright (c) 2020 Tobias Svehagen
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "_main.h"
8 
ZTEST_F(eventfd,test_write_then_read)9 ZTEST_F(eventfd, test_write_then_read)
10 {
11 	eventfd_t val;
12 	int ret;
13 
14 	ret = eventfd_write(fixture->fd, 3);
15 	zassert_true(ret == 0, "write ret %d", ret);
16 
17 	ret = eventfd_write(fixture->fd, 2);
18 	zassert_true(ret == 0, "write ret %d", ret);
19 
20 	ret = eventfd_read(fixture->fd, &val);
21 	zassert_true(ret == 0, "read ret %d", ret);
22 	zassert_true(val == 5, "val == %d", val);
23 
24 	/* Test EFD_SEMAPHORE */
25 	reopen(&fixture->fd, 0, EFD_SEMAPHORE);
26 
27 	ret = eventfd_write(fixture->fd, 3);
28 	zassert_true(ret == 0, "write ret %d", ret);
29 
30 	ret = eventfd_write(fixture->fd, 2);
31 	zassert_true(ret == 0, "write ret %d", ret);
32 
33 	ret = eventfd_read(fixture->fd, &val);
34 	zassert_true(ret == 0, "read ret %d", ret);
35 	zassert_true(val == 1, "val == %d", val);
36 }
37 
ZTEST_F(eventfd,test_zero_shall_not_unblock)38 ZTEST_F(eventfd, test_zero_shall_not_unblock)
39 {
40 	short event;
41 	int ret;
42 
43 	ret = eventfd_write(fixture->fd, 0);
44 	zassert_equal(ret, 0, "fd == %d", fixture->fd);
45 
46 	event = POLLIN;
47 	ret = is_blocked(fixture->fd, &event);
48 	zassert_equal(ret, 1, "eventfd unblocked by zero");
49 }
50 
ZTEST_F(eventfd,test_poll_timeout)51 ZTEST_F(eventfd, test_poll_timeout)
52 {
53 	struct pollfd pfd;
54 	int ret;
55 
56 	pfd.fd = fixture->fd;
57 	pfd.events = POLLIN;
58 
59 	ret = poll(&pfd, 1, 500);
60 	zassert_true(ret == 0, "poll ret %d", ret);
61 }
62 
ZTEST_F(eventfd,test_set_poll_event_block)63 ZTEST_F(eventfd, test_set_poll_event_block)
64 {
65 	reopen(&fixture->fd, TESTVAL, 0);
66 	eventfd_poll_set_common(fixture->fd);
67 }
68 
ZTEST_F(eventfd,test_unset_poll_event_block)69 ZTEST_F(eventfd, test_unset_poll_event_block)
70 {
71 	eventfd_poll_unset_common(fixture->fd);
72 }
73 
74 K_THREAD_STACK_DEFINE(thread_stack, CONFIG_TEST_STACK_SIZE);
75 static struct k_thread thread;
76 
thread_eventfd_read_42(void * arg1,void * arg2,void * arg3)77 static void thread_eventfd_read_42(void *arg1, void *arg2, void *arg3)
78 {
79 	eventfd_t value;
80 	struct eventfd_fixture *fixture = arg1;
81 
82 	zassert_ok(eventfd_read(fixture->fd, &value));
83 	zassert_equal(value, 42);
84 }
85 
ZTEST_F(eventfd,test_read_then_write_block)86 ZTEST_F(eventfd, test_read_then_write_block)
87 {
88 	k_thread_create(&thread, thread_stack, K_THREAD_STACK_SIZEOF(thread_stack),
89 			thread_eventfd_read_42, fixture, NULL, NULL, 0, 0, K_NO_WAIT);
90 
91 	k_msleep(100);
92 
93 	/* this write never occurs */
94 	zassert_ok(eventfd_write(fixture->fd, 42));
95 
96 	/* unreachable code */
97 	k_thread_join(&thread, K_FOREVER);
98 }
99 
thread_eventfd_write(void * arg1,void * arg2,void * arg3)100 static void thread_eventfd_write(void *arg1, void *arg2, void *arg3)
101 {
102 	struct eventfd_fixture *fixture = arg1;
103 
104 	zassert_ok(eventfd_write(fixture->fd, 71));
105 }
106 
ZTEST_F(eventfd,test_write_while_pollin)107 ZTEST_F(eventfd, test_write_while_pollin)
108 {
109 	struct zsock_pollfd fds[] = {
110 		{
111 			.fd = fixture->fd,
112 			.events = ZSOCK_POLLIN,
113 		},
114 	};
115 	eventfd_t value;
116 	int ret;
117 
118 	k_thread_create(&thread, thread_stack, K_THREAD_STACK_SIZEOF(thread_stack),
119 			thread_eventfd_write, fixture, NULL, NULL, 0, 0, K_MSEC(100));
120 
121 	/* Expect 1 event */
122 	ret = zsock_poll(fds, ARRAY_SIZE(fds), 200);
123 	zassert_equal(ret, 1);
124 
125 	zassert_equal(fds[0].revents, ZSOCK_POLLIN);
126 
127 	/* Check value */
128 	zassert_ok(eventfd_read(fixture->fd, &value));
129 	zassert_equal(value, 71);
130 
131 	zassert_ok(k_thread_join(&thread, K_FOREVER));
132 }
133 
thread_eventfd_read(void * arg1,void * arg2,void * arg3)134 static void thread_eventfd_read(void *arg1, void *arg2, void *arg3)
135 {
136 	eventfd_t value;
137 	struct eventfd_fixture *fixture = arg1;
138 
139 	zassert_ok(eventfd_read(fixture->fd, &value));
140 }
141 
ZTEST_F(eventfd,test_read_while_pollout)142 ZTEST_F(eventfd, test_read_while_pollout)
143 {
144 	struct zsock_pollfd fds[] = {
145 		{
146 			.fd = fixture->fd,
147 			.events = ZSOCK_POLLOUT,
148 		},
149 	};
150 	int ret;
151 
152 	zassert_ok(eventfd_write(fixture->fd, UINT64_MAX - 1));
153 
154 	k_thread_create(&thread, thread_stack, K_THREAD_STACK_SIZEOF(thread_stack),
155 			thread_eventfd_read, fixture, NULL, NULL, 0, 0, K_MSEC(100));
156 
157 	/* Expect 1 event */
158 	ret = zsock_poll(fds, ARRAY_SIZE(fds), 200);
159 	zassert_equal(ret, 1);
160 
161 	zassert_equal(fds[0].revents, ZSOCK_POLLOUT);
162 
163 	zassert_ok(k_thread_join(&thread, K_FOREVER));
164 }
165