• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use core::ops;
15 
16 use ylong_io::Interest;
17 
18 const READABLE: usize = 0b0_01;
19 const WRITABLE: usize = 0b0_10;
20 const READ_CLOSED: usize = 0b0_0100;
21 const WRITE_CLOSED: usize = 0b0_1000;
22 
23 cfg_not_ffrt! {
24     use ylong_io::{Event, EventTrait};
25 }
26 
27 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
28 pub struct Ready(usize);
29 
30 #[derive(Debug)]
31 pub(crate) struct ReadyEvent {
32     tick: u8,
33     pub(crate) ready: Ready,
34 }
35 
36 impl Ready {
37     pub const EMPTY: Ready = Ready(0);
38 
39     pub const READABLE: Ready = Ready(READABLE);
40 
41     pub const WRITABLE: Ready = Ready(WRITABLE);
42 
43     pub const READ_CLOSED: Ready = Ready(READ_CLOSED);
44 
45     pub const WRITE_CLOSED: Ready = Ready(WRITE_CLOSED);
46 
47     pub const ALL: Ready = Ready(READABLE | WRITABLE | READ_CLOSED | WRITE_CLOSED);
48 
49     #[cfg(not(feature = "ffrt"))]
from_event(event: &Event) -> Ready50     pub(crate) fn from_event(event: &Event) -> Ready {
51         let mut ready = Ready::EMPTY;
52 
53         if event.is_readable() {
54             ready |= Ready::READABLE;
55         }
56 
57         if event.is_writable() {
58             ready |= Ready::WRITABLE;
59         }
60 
61         if event.is_read_closed() {
62             ready |= Ready::READ_CLOSED;
63         }
64 
65         if event.is_write_closed() {
66             ready |= Ready::WRITE_CLOSED;
67         }
68         ready
69     }
70 
is_empty(self) -> bool71     pub fn is_empty(self) -> bool {
72         self == Ready::EMPTY
73     }
74 
is_readable(self) -> bool75     pub fn is_readable(self) -> bool {
76         (self & Ready::READABLE).0 != 0 || self.is_read_closed()
77     }
78 
is_writable(self) -> bool79     pub fn is_writable(self) -> bool {
80         (self & Ready::WRITABLE).0 != 0 || self.is_write_closed()
81     }
82 
is_read_closed(self) -> bool83     pub fn is_read_closed(self) -> bool {
84         (self & Ready::READ_CLOSED).0 != 0
85     }
86 
is_write_closed(self) -> bool87     pub fn is_write_closed(self) -> bool {
88         (self & Ready::WRITE_CLOSED).0 != 0
89     }
90 
from_usize(val: usize) -> Ready91     pub(crate) fn from_usize(val: usize) -> Ready {
92         Ready(val & Ready::ALL.as_usize())
93     }
94 
as_usize(self) -> usize95     pub(crate) fn as_usize(self) -> usize {
96         self.0
97     }
98 
from_interest(interest: Interest) -> Ready99     pub(crate) fn from_interest(interest: Interest) -> Ready {
100         let mut ready = Ready::EMPTY;
101 
102         if interest.is_readable() {
103             ready |= Ready::READABLE;
104             ready |= Ready::READ_CLOSED;
105         }
106 
107         if interest.is_writable() {
108             ready |= Ready::WRITABLE;
109             ready |= Ready::WRITE_CLOSED;
110         }
111 
112         ready
113     }
114 
intersection(self, interest: Interest) -> Ready115     pub(crate) fn intersection(self, interest: Interest) -> Ready {
116         Ready(self.0 & Ready::from_interest(interest).0)
117     }
118 
satisfies(self, interest: Interest) -> bool119     pub(crate) fn satisfies(self, interest: Interest) -> bool {
120         self.0 & Ready::from_interest(interest).0 != 0
121     }
122 }
123 
124 impl ops::BitOr<Ready> for Ready {
125     type Output = Ready;
126 
127     #[inline]
bitor(self, other: Ready) -> Self::Output128     fn bitor(self, other: Ready) -> Self::Output {
129         Ready(self.0 | other.0)
130     }
131 }
132 
133 impl ops::BitOrAssign<Ready> for Ready {
134     #[inline]
bitor_assign(&mut self, other: Ready)135     fn bitor_assign(&mut self, other: Ready) {
136         self.0 |= other.0
137     }
138 }
139 
140 impl ops::BitAnd<Ready> for Ready {
141     type Output = Ready;
142 
143     #[inline]
bitand(self, other: Ready) -> Self::Output144     fn bitand(self, other: Ready) -> Self::Output {
145         Ready(self.0 & other.0)
146     }
147 }
148 
149 impl ops::Sub<Ready> for Ready {
150     type Output = Ready;
151 
152     #[inline]
sub(self, other: Ready) -> Self::Output153     fn sub(self, other: Ready) -> Self::Output {
154         Ready(self.0 & !other.0)
155     }
156 }
157 
158 impl ReadyEvent {
new(tick: u8, ready: Ready) -> Self159     pub fn new(tick: u8, ready: Ready) -> Self {
160         ReadyEvent { tick, ready }
161     }
162 
get_tick(&self) -> u8163     pub fn get_tick(&self) -> u8 {
164         self.tick
165     }
166 
get_ready(&self) -> Ready167     pub fn get_ready(&self) -> Ready {
168         self.ready
169     }
170 }
171 
172 cfg_ffrt! {
173     fn is_readable(event: i32) -> bool {
174         (event as libc::c_int & libc::EPOLLIN) != 0
175             || (event as libc::c_int & libc::EPOLLPRI) != 0
176     }
177 
178     fn is_writable(event: i32) -> bool {
179         (event as libc::c_int & libc::EPOLLOUT) != 0
180     }
181 
182     fn is_read_closed(event: i32) -> bool {
183         event as libc::c_int & libc::EPOLLHUP != 0
184             || (event as libc::c_int & libc::EPOLLIN != 0
185                 && event as libc::c_int & libc::EPOLLRDHUP != 0)
186     }
187 
188     fn is_write_closed(event: i32) -> bool {
189         event as libc::c_int & libc::EPOLLHUP != 0
190             || (event as libc::c_int & libc::EPOLLOUT != 0
191                 && event as libc::c_int & libc::EPOLLERR != 0)
192             || event as libc::c_int == libc::EPOLLERR
193     }
194 
195     pub(crate) fn from_event_inner(event: i32) -> Ready {
196         let mut ready = Ready::EMPTY;
197         if is_readable(event) {
198             ready |= Ready::READABLE;
199         }
200 
201         if is_writable(event) {
202             ready |= Ready::WRITABLE;
203         }
204 
205         if is_read_closed(event) {
206             ready |= Ready::READ_CLOSED;
207         }
208 
209         if is_write_closed(event) {
210             ready |= Ready::WRITE_CLOSED;
211         }
212         ready
213     }
214 }
215 
216 // @title  ready from_event function ut test
217 // @design conditions of use override
218 // @precon none
219 // @brief  1. Create an event
220 //         2. Call from_event
221 //         3. Verify the returned results
222 // @expect 1. Event readable to get readable Ready instances
223 //         2. Event writable, call writable Ready instances
224 //         3. Event Read Close, Call Read Close Ready Instance
225 //         4. Event Write Close, Call Write Close Ready Instance
226 // @auto  Yes
227 #[test]
228 #[cfg(feature = "tcp")]
ut_ready_from_event()229 fn ut_ready_from_event() {
230     ut_ready_from_event_01();
231     ut_ready_from_event_02();
232     ut_ready_from_event_03();
233     ut_ready_from_event_04();
234 
235     // Readable
236     fn ut_ready_from_event_01() {
237         let mut event = libc::epoll_event {
238             events: 0b00,
239             u64: 0,
240         };
241         event.events |= libc::EPOLLIN as u32;
242         let ready = Ready::from_event(&event);
243         assert_eq!(ready.0, 0b01);
244     }
245 
246     // Writable
247     fn ut_ready_from_event_02() {
248         let mut event = libc::epoll_event {
249             events: 0b00,
250             u64: 0,
251         };
252         event.events |= libc::EPOLLOUT as u32;
253         let ready = Ready::from_event(&event);
254         assert_eq!(ready.0, 0b10);
255     }
256 
257     // Read off
258     fn ut_ready_from_event_03() {
259         let mut event = libc::epoll_event {
260             events: 0b00,
261             u64: 0,
262         };
263         event.events |= (libc::EPOLLIN | libc::EPOLLRDHUP) as u32;
264         let ready = Ready::from_event(&event);
265         assert_eq!(ready.0, 0b101);
266     }
267 
268     // Write Off
269     fn ut_ready_from_event_04() {
270         let mut event = libc::epoll_event {
271             events: 0x00,
272             u64: 0,
273         };
274         event.events |= (libc::EPOLLOUT | libc::EPOLLERR) as u32;
275         let ready = Ready::from_event(&event);
276         assert_eq!(ready.0, 0b1010);
277     }
278 }
279 
280 /// UT test cases for ready from_usize function
281 ///
282 /// # Brief
283 /// 1. Enter a usize, call from_usize
284 /// 2. Verify the returned results
285 #[test]
ut_ready_from_usize()286 fn ut_ready_from_usize() {
287     let ready = Ready::from_usize(0x01);
288     assert_eq!(ready.0, 0x01);
289 }
290 
291 /// UT test cases for ready is_empty function
292 ///
293 /// # Brief
294 /// 1. Create a Ready
295 /// 2. Call is_empty
296 /// 3. Verify the returned results
297 #[test]
ut_ready_is_empty()298 fn ut_ready_is_empty() {
299     let ready = Ready::from_usize(0x00);
300     assert!(ready.is_empty());
301 
302     let ready = Ready::from_usize(0x01);
303     assert!(!ready.is_empty());
304 }
305 
306 /// UT test cases for ready is_readable function
307 ///
308 /// # Brief
309 /// 1. Create a Ready
310 /// 2. Call is_readable
311 /// 3. Verify the returned results
312 #[test]
ut_ready_is_readable()313 fn ut_ready_is_readable() {
314     let ready = Ready::from_usize(0x01);
315     assert!(ready.is_readable());
316 
317     let ready = Ready::from_usize(0x02);
318     assert!(!ready.is_readable());
319 }
320 
321 /// UT test cases for ready is_writable function
322 ///
323 /// # Brief
324 /// 1. Create a Ready
325 /// 2. Call is_writable
326 /// 3. Verify the returned results
327 #[test]
ut_ready_is_writable()328 fn ut_ready_is_writable() {
329     let ready = Ready::from_usize(0x02);
330     assert!(ready.is_writable());
331 
332     let ready = Ready::from_usize(0x01);
333     assert!(!ready.is_writable());
334 }
335 
336 /// UT test cases for ready is_read_closed function
337 ///
338 /// # Brief
339 /// 1. Create a Ready
340 /// 2. Call is_read_closed
341 /// 3. Verify the returned results
342 #[test]
ut_ready_is_read_closed()343 fn ut_ready_is_read_closed() {
344     let ready = Ready::from_usize(0x04);
345     assert!(ready.is_read_closed());
346 
347     let ready = Ready::from_usize(0x01);
348     assert!(!ready.is_read_closed());
349 }
350 
351 /// UT test cases for ready is_write_closed function
352 ///
353 /// # Brief
354 /// 1. Create a Ready
355 /// 2. Call is_write_closed
356 /// 3. Verify the returned results
357 #[test]
ut_ready_is_write_closed()358 fn ut_ready_is_write_closed() {
359     let ready = Ready::from_usize(0x08);
360     assert!(ready.is_write_closed());
361 
362     let ready = Ready::from_usize(0x01);
363     assert!(!ready.is_write_closed());
364 }
365 
366 /// UT test cases for ready as_usize function
367 ///
368 /// # Brief
369 /// 1. Create a Ready
370 /// 2. Call as_usize
371 /// 3. Verify the returned results
372 #[test]
ut_ready_as_usize()373 fn ut_ready_as_usize() {
374     let ready = Ready::from_usize(0x08);
375     assert_eq!(ready.as_usize(), 0x08);
376 }
377 
378 /// UT test cases for ready from_interest function
379 ///
380 /// # Brief
381 /// 1. Create a Interest instances
382 /// 2. Call from_interest
383 /// 3. Verify the returned results
384 #[test]
ut_ready_from_interest()385 fn ut_ready_from_interest() {
386     let interest = Interest::READABLE;
387     let ready = Ready::from_interest(interest);
388     assert_eq!(ready.as_usize(), 0b101);
389 
390     let interest = Interest::WRITABLE;
391     let ready = Ready::from_interest(interest);
392     assert_eq!(ready.as_usize(), 0b1010);
393 }
394 
395 /// UT test cases for ready intersection function
396 ///
397 /// # Brief
398 /// 1. Create a Interest instances and a Ready instances
399 /// 2. Call intersection
400 /// 3. Verify the returned results
401 #[test]
ut_ready_intersection()402 fn ut_ready_intersection() {
403     let interest = Interest::READABLE;
404     let ready = Ready::from_usize(0b1111);
405     let res = ready.intersection(interest);
406     assert_eq!(res.0, 0b0101);
407 }
408 
409 /// UT test cases for ready satisfies function
410 ///
411 /// # Brief
412 /// 1. Create a Interest instances, and a Ready instances
413 /// 2. Call satisfies
414 /// 3. Verify the returned results
415 #[test]
ut_ready_satisfies()416 fn ut_ready_satisfies() {
417     let interest = Interest::READABLE;
418     let ready = Ready::from_usize(0b1111);
419     assert!(ready.satisfies(interest));
420 
421     let ready = Ready::from_usize(0b0000);
422     assert!(!ready.satisfies(interest));
423 }
424 
425 /// UT test cases for ready bitor function
426 ///
427 /// # Brief
428 /// 1. Create two Ready instances
429 /// 2. Call bitor or use | logical operators
430 /// 3. Verify the returned results
431 #[test]
ut_ready_bitor()432 fn ut_ready_bitor() {
433     let ready1 = Ready::from_usize(0b1010);
434     let ready2 = Ready::from_usize(0b0101);
435     let ready3 = ready1 | ready2;
436     assert_eq!(ready3.0, 0b1111);
437 }
438 
439 /// UT test cases for ready bitor_assign function
440 ///
441 /// # Brief
442 /// 1. Create two Ready instances
443 /// 2. Call bitor_assign or use |= logical operators
444 /// 3. Verify the returned results
445 #[test]
ut_ready_bitor_assign()446 fn ut_ready_bitor_assign() {
447     let mut ready1 = Ready::from_usize(0b1010);
448     let ready2 = Ready::from_usize(0b0101);
449     ready1 |= ready2;
450     assert_eq!(ready1.0, 0b1111);
451 }
452 
453 /// UT test cases for ready bitand function
454 ///
455 /// # Brief
456 /// 1. Create two Ready instances
457 /// 2. Call bitand or use & logical operators
458 /// 3. Verify the returned results
459 #[test]
ut_ready_bitand()460 fn ut_ready_bitand() {
461     let ready1 = Ready::from_usize(0b1010);
462     let ready2 = Ready::from_usize(0b0101);
463     let ready = ready1 & ready2;
464     assert_eq!(ready.0, 0b0000);
465 }
466 
467 /// UT test cases for ready bitsub function
468 ///
469 /// # Brief
470 /// 1. Create two Ready instances
471 /// 2. Call bitsub or use - logical operators
472 /// 3. Verify the returned results
473 #[test]
ut_ready_bitsub()474 fn ut_ready_bitsub() {
475     let ready1 = Ready::from_usize(0b1111);
476     let ready2 = Ready::from_usize(0b0101);
477     let ready = ready1 - ready2;
478     assert_eq!(ready.0, 0b1010);
479 }
480 
481 /// UT test cases for ready_event new function
482 ///
483 /// # Brief
484 /// 1. Call new
485 /// 2. Verify the returned results
486 #[test]
ut_ready_event_new()487 fn ut_ready_event_new() {
488     let ready_event = ReadyEvent::new(1u8, Ready::from_usize(0b0101));
489     assert_eq!(ready_event.tick, 1u8);
490     assert_eq!(ready_event.ready.0, 0b0101);
491 }
492 
493 /// UT test cases for ready_event get_tick function
494 ///
495 /// # Brief
496 /// 1. Create a ready_event
497 /// 2. Call get_tick
498 /// 3. Verify the returned results
499 #[test]
ut_ready_event_get_tick()500 fn ut_ready_event_get_tick() {
501     let ready_event = ReadyEvent::new(1u8, Ready::from_usize(0b0101));
502     assert_eq!(ready_event.get_tick(), 1u8);
503 }
504 
505 /// UT test cases for ready_event get_ready function
506 ///
507 /// # Brief
508 /// 1. Create a ready_event
509 /// 2. Call get_ready
510 /// 3. Verify the returned results
511 #[test]
ut_ready_event_get_ready()512 fn ut_ready_event_get_ready() {
513     let ready_event = ReadyEvent::new(1u8, Ready::from_usize(0b0101));
514     assert_eq!(ready_event.get_ready().0, 0b0101);
515 }
516