1 /* pipe_r.c */
2 
3 /*
4  * Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include "receiver.h"
10 #include "master.h"
11 
12 /*
13  * Function prototypes.
14  */
15 int pipeget(struct k_pipe *pipe, enum pipe_options option,
16 			int size, int count, unsigned int *time);
17 
18 /*
19  * Function declarations.
20  */
21 
22 /* pipes transfer speed test */
23 
24 /**
25  * @brief Receive task
26  */
piperecvtask(void)27 void piperecvtask(void)
28 {
29 	int getsize;
30 	unsigned int gettime;
31 	int getcount;
32 	int pipe;
33 	int prio;
34 	struct getinfo getinfo;
35 
36 	/* matching (ALL_N) */
37 
38 	for (getsize = 8; getsize <= MESSAGE_SIZE_PIPE; getsize <<= 1) {
39 		for (pipe = 0; pipe < 3; pipe++) {
40 			getcount = NR_OF_PIPE_RUNS;
41 			pipeget(test_pipes[pipe], _ALL_N, getsize,
42 				getcount, &gettime);
43 			getinfo.time = gettime;
44 			getinfo.size = getsize;
45 			getinfo.count = getcount;
46 			/* acknowledge to master */
47 			k_msgq_put(&CH_COMM, &getinfo, K_FOREVER);
48 		}
49 	}
50 
51 	for (prio = 0; prio < 2; prio++) {
52 		/* non-matching (1_TO_N) */
53 		for (getsize = (MESSAGE_SIZE_PIPE); getsize >= 8; getsize >>= 1) {
54 			getcount = MESSAGE_SIZE_PIPE / getsize;
55 			for (pipe = 0; pipe < 3; pipe++) {
56 				/* size*count == MESSAGE_SIZE_PIPE */
57 				pipeget(test_pipes[pipe], _1_TO_N,
58 						getsize, getcount, &gettime);
59 				getinfo.time = gettime;
60 				getinfo.size = getsize;
61 				getinfo.count = getcount;
62 				/* acknowledge to master */
63 				k_msgq_put(&CH_COMM, &getinfo, K_FOREVER);
64 			}
65 		}
66 	}
67 
68 }
69 
70 
71 /**
72  * @brief Read a data portion from the pipe and measure time
73  *
74  * @return 0 on success, 1 on error
75  *
76  * @param pipe     Pipe to read data from.
77  * @param option   _ALL_TO_N or _1_TO_N.
78  * @param size     Data chunk size.
79  * @param count    Number of data chunks.
80  * @param time     Total write time.
81  */
pipeget(struct k_pipe * pipe,enum pipe_options option,int size,int count,unsigned int * time)82 int pipeget(struct k_pipe *pipe, enum pipe_options option, int size, int count,
83 			unsigned int *time)
84 {
85 	int i;
86 	unsigned int t;
87 	timing_t  start;
88 	timing_t  end;
89 	size_t sizexferd_total = 0;
90 	size_t size2xfer_total = size * count;
91 
92 	/* sync with the sender */
93 	k_sem_take(&SEM0, K_FOREVER);
94 	start = timing_timestamp_get();
95 	for (i = 0; option == _1_TO_N || (i < count); i++) {
96 		size_t sizexferd = 0;
97 		size_t size2xfer = MIN(size, size2xfer_total - sizexferd_total);
98 		int ret;
99 
100 		ret = k_pipe_get(pipe, data_recv, size2xfer,
101 				 &sizexferd, option, K_FOREVER);
102 
103 		if (ret != 0) {
104 			return 1;
105 		}
106 
107 		if (option == _ALL_N  && sizexferd != size2xfer) {
108 			return 1;
109 		}
110 
111 		sizexferd_total += sizexferd;
112 		if (size2xfer_total == sizexferd_total) {
113 			break;
114 		}
115 
116 		if (size2xfer_total < sizexferd_total) {
117 			return 1;
118 		}
119 	}
120 
121 	end = timing_timestamp_get();
122 	t = (unsigned int) timing_cycles_get(&start, &end);
123 	*time = SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, count);
124 
125 	return 0;
126 }
127