Linux/Qnx: MessageQBench test must check initial MSG put
[ipc/ipcdev.git] / linux / src / tests / MessageQBench.c
1 /*
2  * Copyright (c) 2012-2014, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /* =============================================================================
33  *  @file   MessageQBench.c
34  *
35  *  @brief  Benchmark application for MessageQ module between MPU/Remote Proc
36  *
37  *  ============================================================================
38  */
40 /* Standard headers */
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <time.h>
44 #include <sys/param.h>
46 /* IPC Headers */
47 #include <ti/ipc/Std.h>
48 #include <ti/ipc/Ipc.h>
49 #include <ti/ipc/MessageQ.h>
51 #define MINPAYLOADSIZE      (2 * sizeof(UInt32))
53 /* App defines:  Must match on remote proc side: */
54 #define HEAPID              0u
55 #define SLAVE_MESSAGEQNAME  "SLAVE"
56 #define MPU_MESSAGEQNAME    "HOST"
58 #define PROC_ID_DFLT        1     /* Host is zero, remote cores start at 1 */
59 #define NUM_LOOPS_DFLT      1000  /* Number of transfers to be tested. */
61 typedef struct SyncMsg {
62     MessageQ_MsgHeader header;
63     UInt32 numLoops;  /* also used for msgId */
64     UInt32 print;
65 } SyncMsg ;
67 long diff(struct timespec start, struct timespec end)
68 {
69     struct timespec temp;
71     if ((end.tv_nsec - start.tv_nsec) < 0) {
72         temp.tv_sec = end.tv_sec - start.tv_sec-1;
73         temp.tv_nsec = 1000000000UL + end.tv_nsec - start.tv_nsec;
74     } else {
75         temp.tv_sec = end.tv_sec - start.tv_sec;
76         temp.tv_nsec = end.tv_nsec - start.tv_nsec;
77     }
79     return (temp.tv_sec * 1000000UL + temp.tv_nsec / 1000);
80 }
82 Int MessageQApp_execute(UInt32 numLoops, UInt32 payloadSize, UInt16 procId)
83 {
84     Int32                    status     = 0;
85     MessageQ_Msg             msg        = NULL;
86     MessageQ_Params          msgParams;
87     UInt32                   i;
88     MessageQ_QueueId         queueId = MessageQ_INVALIDMESSAGEQ;
89     MessageQ_Handle          msgqHandle;
90     char                     remoteQueueName[64];
91     struct timespec          start, end;
92     long                     elapsed;
93     UInt32                   msgId;
95     printf("Entered MessageQApp_execute\n");
97     /* Create the local Message Queue for receiving. */
98     MessageQ_Params_init(&msgParams);
99     msgqHandle = MessageQ_create(MPU_MESSAGEQNAME, &msgParams);
100     if (msgqHandle == NULL) {
101         printf("Error in MessageQ_create\n");
102         goto exit;
103     }
104     else {
105         printf("Local MessageQId: 0x%x\n", MessageQ_getQueueId(msgqHandle));
106     }
108     sprintf(remoteQueueName, "%s_%s", SLAVE_MESSAGEQNAME,
109              MultiProc_getName(procId));
111     /* Poll until remote side has its messageQ created before we send: */
112     do {
113         status = MessageQ_open(remoteQueueName, &queueId);
114         sleep (1);
115     } while (status == MessageQ_E_NOTFOUND);
117     if (status < 0) {
118         printf("Error in MessageQ_open [%d]\n", status);
119         goto cleanup;
120     }
121     else {
122         printf("Remote queueId  [0x%x]\n", queueId);
123     }
125     msg = MessageQ_alloc(HEAPID, sizeof(SyncMsg) + payloadSize);
126     if (msg == NULL) {
127         printf("Error in MessageQ_alloc\n");
128         goto close_cleanup;
129     }
131     /* handshake with remote to set the number of loops */
132     MessageQ_setReplyQueue(msgqHandle, msg);
133     ((SyncMsg *)msg)->numLoops = numLoops;
134     ((SyncMsg *)msg)->print = FALSE;
136     status = MessageQ_put(queueId, msg);
137     if (status < 0) {
138         printf("MessageQ_put handshake failed [%d]\n", status);
139         goto free_cleanup;
140      }
142     MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER);
144     printf("Exchanging %d messages with remote processor %s...\n",
145            numLoops, MultiProc_getName(procId));
147     clock_gettime(CLOCK_REALTIME, &start);
149     for (i = 1 ; i <= numLoops; i++) {
150         ((SyncMsg *)msg)->numLoops = i;
152         /* Have the remote proc reply to this message queue */
153         MessageQ_setReplyQueue(msgqHandle, msg);
155         status = MessageQ_put(queueId, msg);
156         if (status < 0) {
157             printf("Error in MessageQ_put [%d]\n", status);
158             break;
159         }
161         status = MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER);
163         if (status < 0) {
164             printf("Error in MessageQ_get [%d]\n", status);
165             break;
166         }
167         else {
168             /* Validate the returned message */
169             msgId = ((SyncMsg *)msg)->numLoops;
170             if ((msg != NULL) && (msgId != i)) {
171                 printf("Data integrity failure!\n"
172                         "    Expected %d\n"
173                         "    Received %d\n",
174                         i, msgId);
175                 break;
176             }
177         }
178     }
180     clock_gettime(CLOCK_REALTIME, &end);
181     elapsed = diff(start, end);
183     if (numLoops > 0) {
184         printf("%s: Avg round trip time: %ld usecs\n",
185                MultiProc_getName(procId), elapsed / numLoops);
186     }
188 free_cleanup:
189     MessageQ_free(msg);
190 close_cleanup:
191     MessageQ_close(&queueId);
193 cleanup:
194     status = MessageQ_delete(&msgqHandle);
195     if (status < 0) {
196         printf ("Error in MessageQ_delete [%d]\n", status);
197     }
199 exit:
200     printf("Leaving MessageQApp_execute\n\n");
202     return (status);
205 int main (int argc, char * argv[])
207     Int32 status = 0;
208     UInt32 numLoops = NUM_LOOPS_DFLT;
209     UInt32 payloadSize = MINPAYLOADSIZE;
210     UInt16 procId = PROC_ID_DFLT;
212     /* Parse args: */
213     if (argc > 1) {
214         numLoops = strtoul(argv[1], NULL, 0);
215     }
217     if (argc > 2) {
218         payloadSize = MAX(strtoul(argv[2], NULL, 0), MINPAYLOADSIZE);
219     }
221     if (argc > 3) {
222         procId  = atoi(argv[3]);
223     }
225     if (argc > 4) {
226         printf("Usage: %s [<numLoops>] [<payloadSize>] [<ProcId>]\n", argv[0]);
227         printf("\tDefaults: numLoops: %d; payloadSize: %d, ProcId: %d\n",
228                    NUM_LOOPS_DFLT, MINPAYLOADSIZE, PROC_ID_DFLT);
229         exit(0);
230     }
232     status = Ipc_start();
234     if (procId >= MultiProc_getNumProcessors()) {
235         printf("ProcId must be less than %d\n", MultiProc_getNumProcessors());
236         Ipc_stop();
237         exit(0);
238     }
239     printf("Using numLoops: %d; payloadSize: %d, procId : %d\n",
240             numLoops, payloadSize, procId);
242     if (status >= 0) {
243         MessageQApp_execute(numLoops, payloadSize, procId);
244         Ipc_stop();
245     }
246     else {
247         printf("Ipc_start failed: status = %d\n", status);
248     }
250     return (status);