Install test binaries to bin/tests
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / samples / hlos / rpmsg-rpc-stress / usr / tests_rpc_stress.c
1 /*
2  * Copyright (c) 2013, 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  * tests_rpc_stress.c
34  *
35  * Stress tests for rpmsg-rpc.
36  *
37  */
39 #include <sys/select.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 #include <errno.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include <stdlib.h>
47 #include <unistd.h>
48 #include <pthread.h>
49 #include <time.h>
50 #include <stdbool.h>
51 #include <semaphore.h>
53 #include "ti/ipc/rpmsg_rpc.h"
56 typedef struct {
57     int a;
58 } fxn_triple_args;
60 /* Note: Set bit 31 to indicate static function indicies:
61  * This function order will be hardcoded on BIOS side, hence preconfigured:
62  */
63 #define FXN_IDX_FXNTRIPLE            (1 | 0x80000000)
65 #define NUM_ITERATIONS               20
67 static int test_status = 0;
68 static bool runTest = true;
70 int exec_cmd(int fd, char *msg, size_t len, char *reply_msg, int *reply_len)
71 {
72     int ret = 0;
74     ret = write(fd, msg, len);
75     if (ret < 0) {
76         perror("Can't write to rpc_example instance");
77         return -1;
78     }
80     /* Now, await normal function result from rpc_example service:
81      * Note: len should be max length of response expected.
82      */
83     ret = read(fd, reply_msg, len);
84     if (ret < 0) {
85         perror("Can't read from rpc_example instance");
86         return -1;
87     }
88     else {
89         *reply_len = ret;
90     }
91     return 0;
92 }
94 int send_cmd(int fd, char *msg, int len)
95 {
96     int ret = 0;
98     ret = write(fd, msg, len);
99     if (ret < 0) {
100          perror("Can't write to rpc_example instance\n");
101          return -1;
102     }
104     return(0);
107 int recv_cmd(int fd, int len, char *reply_msg, int *reply_len)
109     int ret = 0;
111     /* Now, await normal function result from rpc_example service: */
112     // Note: len should be max length of response expected.
113     ret = read(fd, reply_msg, len);
114     if (ret < 0) {
115          perror("Can't read from rpc_example instance\n");
116          return -1;
117     }
118     else {
119           *reply_len = ret;
120     }
121     return(0);
124 typedef struct test_exec_args {
125     int fd;
126     int start_num;
127     int test_num;
128     sem_t * sem;
129     int thread_num;
130 } test_exec_args;
132 static pthread_t * clientThreads = NULL;
133 static sem_t * clientSems = NULL;
134 static char **clientPackets = NULL;
135 static bool *readMsg = NULL;
136 static int *fds;
138 void * test_exec_call(void * arg)
140     int               i;
141     int               packet_len;
142     int               reply_len;
143     char              packet_buf[512] = {0};
144     char              return_buf[512] = {0};
145     test_exec_args    *args = (test_exec_args *) arg;
146     int               fd = args->fd;
147     struct rppc_function *function;
148     struct rppc_function_return *returned;
150     for (i = args->start_num; i < args->start_num + NUM_ITERATIONS; i++) {
151         function = (struct rppc_function *)packet_buf;
152         function->fxn_id = FXN_IDX_FXNTRIPLE;
153         function->num_params = 1;
154         function->params[0].type = RPPC_PARAM_TYPE_ATOMIC;
155         function->params[0].size = sizeof(int);
156         function->params[0].data = i;
157         function->num_translations = 0;
159         returned = (struct rppc_function_return *)return_buf;
161         /* Exec command: */
162         packet_len = sizeof(struct rppc_function) +\
163                      (function->num_translations * \
164                       sizeof(struct rppc_param_translation));
165         if (args->test_num == 1)  {
166             if (exec_cmd(fd, (char *)packet_buf, packet_len,
167                          (char *)return_buf, &reply_len)) {
168                 test_status = -1;
169                 break;
170             }
171         }
172         else if (args->test_num == 2 || args->test_num == 3) {
173             if (send_cmd(fd, (char *)packet_buf, packet_len)) {
174                 test_status = -1;
175                 break;
176             }
177             sem_wait(&clientSems[args->thread_num]);
178             memcpy(return_buf, clientPackets[args->thread_num], 512);
179             readMsg[args->thread_num] = true;
180         }
181        if (i * 3 != returned->status) {
182            printf ("rpc_stress: "
183                    "called fxnTriple(%d), result = %d, expected %d\n",
184                         function->params[0].data, returned->status, i * 3);
185            test_status = -1;
186            break;
187        }
188        else {
189            printf ("rpc_stress: called fxnTriple(%d), result = %d\n",
190                         function->params[0].data, returned->status);
191        }
192     }
194     return NULL;
197 void * test_select_thread (void * arg)
199     int fd;
200     int reply_len;
201     char return_buf[512] = {0};
202     struct rppc_function_return *rtn_packet =
203                                (struct rppc_function_return *)return_buf;
204     int n, i;
205     fd_set rfd;
206     int max_fd = -1;
208     while (runTest) {
209         FD_ZERO(&rfd);
210         for (i = 0; i < (int)arg; i++) {
211             FD_SET(fds[i], &rfd);
212             max_fd = max(max_fd, fds[i]);
213         }
214         n = select(1 + max_fd, &rfd, NULL, NULL, NULL);
215         switch (n) {
216             case -1:
217                 perror("select");
218                 return NULL;
219             default:
220                 for (i = 0; i < (int)arg; i++) {
221                     if (FD_ISSET(fds[i], &rfd)) {
222                         fd = fds[i];
223                         break;
224                     }
225                 }
226                 break;
227         }
228         if (recv_cmd(fd, 512, (char *)rtn_packet, &reply_len)) {
229             test_status = -1;
230             printf("test_select_thread: recv_cmd failed!");
231             break;
232         }
234         if (runTest == false)
235             break;
237         /* Decode reply: */
238         while (readMsg[i] == false) {
239             sleep(1);
240         }
241         memcpy(clientPackets[i], rtn_packet, 512);
242         readMsg[i] = false;
243         sem_post(&clientSems[i]);
244     }
245     return NULL;
248 void * test_read_thread (void * arg)
250     int fd = (int)arg;
251     int reply_len;
252     char  return_buf[512] = {0};
253     struct rppc_function_return *rtn_packet =
254                                (struct rppc_function_return *)return_buf;
255     int               packet_id;
257     while (runTest) {
258         if (recv_cmd(fd, 512, (char *)rtn_packet, &reply_len)) {
259             test_status = -1;
260             printf("test_read_tread: recv_cmd failed!");
261             break;
262         }
264         if (runTest == false)
265             break;
267         /* Decode reply: */
268         packet_id = ((rtn_packet->status / 3) - 1) / NUM_ITERATIONS;
269         while (readMsg[packet_id] == false) {
270             sleep(1);
271         }
272         memcpy(clientPackets[packet_id], rtn_packet, 512);
273         readMsg[packet_id] = false;
274         sem_post(&clientSems[packet_id]);
275     }
276     return NULL;
279 int test_rpc_stress_select(int core_id, int num_comps)
281     int ret = 0;
282     int i = 0, j = 0;
283     struct rppc_create_instance connreq;
284     struct rppc_function *function;
285     pthread_t select_thread;
286     int               packet_len;
287     char              packet_buf[512] = {0};
288     test_exec_args args[num_comps];
290     fds = malloc (sizeof(int) * num_comps);
291     if (!fds) {
292         return -1;
293     }
294     for (i = 0; i < num_comps; i++) {
295         /* Connect to the rpc_example ServiceMgr on the specified core: */
296         if (core_id == 0) {
297             fds[i] = open("/dev/rpmsg-omx0", O_RDWR);
298             if (fds[i] < 0) {
299                 perror("Can't open OMX device");
300                 ret = -1;
301                 break;
302             }
303             strcpy(connreq.name, "rpmsg-omx0");
304         }
305         else if (core_id == 1) {
306             fds[i] = open("/dev/rpc_example", O_RDWR);
307             if (fds[i] < 0) {
308                 perror("Can't open rpc_example device");
309                 break;
310             }
311             strcpy(connreq.name, "rpc_example");
312         }
313         else if (core_id == 2) {
314             fds[i] = open("/dev/rpmsg-omx2", O_RDWR);
315             if (fds[i] < 0) {
316                 perror("Can't open OMX device");
317                 break;
318             }
319             strcpy(connreq.name, "rpmsg-omx2");
320         }
321         /* Create an rpc_example server instance, and rebind its address to this
322         * file descriptor.
323         */
324         ret = ioctl(fds[i], RPPC_IOC_CREATE, &connreq);
325         if (ret < 0) {
326             perror("Can't connect to rpc_example instance");
327             close(fds[i]);
328             break;
329         }
330         printf("rpc_sample: Connected to %s\n", connreq.name);
331     }
332     if (i != num_comps) {
333         /* cleanup */
334         for (j = 0; j < i; j++) {
335             ret = close(fds[j]);
336             if (ret < 0) {
337                 perror("Can't close rpc_example fd ??");
338             }
339         }
340         free(fds);
341         return -1;
342     }
344     clientSems = malloc(sizeof(sem_t) * num_comps);
345     if (!clientSems) {
346         free(clientThreads);
347         for (i = 0; i < num_comps; i++) {
348             ret = close(fds[i]);
349             if (ret < 0) {
350                 perror("Can't close rpc_example fd ??");
351             }
352         }
353         return -1;
354     }
356     readMsg = malloc(sizeof(bool) * num_comps);
357     if (!readMsg) {
358         free(clientSems);
359         free(clientThreads);
360         for (i = 0; i < num_comps; i++) {
361             ret = close(fds[i]);
362             if (ret < 0) {
363                 perror("Can't close rpc_example fd ??");
364             }
365         }
366         return -1;
367     }
369     clientPackets = malloc(sizeof(char *) * num_comps);
370     if (!clientPackets) {
371         free(readMsg);
372         free(clientSems);
373         free(clientThreads);
374         for (i = 0; i < num_comps; i++) {
375             ret = close(fds[i]);
376             if (ret < 0) {
377                 perror("Can't close rpc_example fd ??");
378             }
379         }
380         return -1;
381     }
383     for (i = 0; i < num_comps; i++) {
384         clientPackets[i] = malloc(512 * sizeof(char));
385         if (!clientPackets[i]) {
386             for (j = 0; j < i; j++) {
387                 free(clientPackets[j]);
388             }
389             free(clientPackets);
390             free(readMsg);
391             free(clientSems);
392             free(clientThreads);
393             for (i = 0; i < num_comps; i++) {
394                 ret = close(fds[i]);
395                 if (ret < 0) {
396                     perror("Can't close rpc_example fd ??");
397                 }
398             }
399             return -1;
400         }
401     }
403     ret = pthread_create(&select_thread, NULL, test_select_thread,
404                          (void *)num_comps);
405     if (ret < 0) {
406         perror("Can't create thread");
407         ret = -1;
408     }
410     clientThreads = malloc(sizeof(pthread_t) * num_comps);
411     if (!clientThreads) {
412         for (i = 0; i < num_comps; i++) {
413             ret = close(fds[i]);
414             if (ret < 0) {
415                 perror("Can't close rpc_example fd ??");
416             }
417         }
418         free(fds);
419         return -1;
420     }
422     for ( i = 0; i < num_comps; i++) {
423         ret = sem_init(&clientSems[i], 0, 0);
424         args[i].fd = fds[i];
425         args[i].start_num = 1;
426         args[i].test_num = 3;
427         args[i].sem = &clientSems[i];
428         args[i].thread_num = i;
429         readMsg[i] = true;
430         ret = pthread_create(&clientThreads[i], NULL, test_exec_call,
431                              (void *)&args[i]);
432         if (ret < 0) {
433             perror("Can't create thread");
434             ret = -1;
435             break;
436         }
437         printf("Created thread %d\n", i);
438     }
440     for (j = 0; j < i; j++) {
441         printf("Join thread %d\n", j);
442         pthread_join(clientThreads[j], NULL);
443     }
445     free(clientThreads);
447     function = (struct rppc_function *)packet_buf;
448     function->fxn_id = FXN_IDX_FXNTRIPLE;
449     function->num_params = 1;
450     function->params[0].type = RPPC_PARAM_TYPE_ATOMIC;
451     function->params[0].size = sizeof(int);
452     function->params[0].data = i;
453     function->num_translations = 0;
455     /* Exec command: */
456     packet_len = sizeof(struct rppc_function) +\
457                  (function->num_translations *\
458                   sizeof(struct rppc_param_translation));
460     runTest = false;
461     if (send_cmd(fds[0], (char *)packet_buf, packet_len)) {
462         test_status = -1;
463     }
465     pthread_join(select_thread, NULL);
467     for (i = 0; i < num_comps; i++) {
468         free(clientPackets[i]);
469     }
470     free(clientPackets);
471     free(readMsg);
472     free(clientSems);
474     for (i = 0; i < num_comps; i++) {
475         /* Terminate connection and destroy rpc_example instance */
476         ret = close(fds[i]);
477         if (ret < 0) {
478             perror("Can't close rpc_example fd ??");
479             ret = -1;
480         }
481         printf("rpc_sample: Closed connection to %s!\n", connreq.name);
482     }
484     free(fds);
485     return ret;
488 int test_rpc_stress_multi_threads(int core_id, int num_threads)
490     int ret = 0;
491     int i = 0, j = 0;
492     int fd;
493     int packet_len;
494     char packet_buf[512] = {0};
495     pthread_t read_thread;
496     struct rppc_create_instance connreq;
497     struct rppc_function *function;
498     test_exec_args args[num_threads];
500     /* Connect to the rpc_example ServiceMgr on the specified core: */
501     if (core_id == 0) {
502         fd = open("/dev/rpmsg-omx0", O_RDWR);
503         if (fd < 0) {
504             perror("Can't open OMX device");
505             return -1;
506         }
507             strcpy(connreq.name, "rpmsg-omx0");
509     }
510     else if (core_id == 1) {
511         fd = open("/dev/rpc_example", O_RDWR);
512         if (fd < 0) {
513             perror("Can't open rpc_example device");
514             return -1;
515         }
516             strcpy(connreq.name, "rpc_example");
517     }
518     else if (core_id == 2) {
519         fd = open("/dev/rpmsg-omx2", O_RDWR);
520         if (fd < 0) {
521             perror("Can't open OMX device");
522             return -1;
523         }
524             strcpy(connreq.name, "rpmsg-omx2");
525     }
526     /* Create an rpc_example server instance, and rebind its address to this
527     * file descriptor.
528     */
529     ret = ioctl(fd, RPPC_IOC_CREATE, &connreq);
530     if (ret < 0) {
531         perror("Can't connect to rpc_example instance");
532         close(fd);
533         return -1;
534     }
535     printf("rpc_sample: Connected to %s\n", connreq.name);
537     clientThreads = malloc(sizeof(pthread_t) * num_threads);
538     if (!clientThreads) {
539         ret = close(fd);
540         return -1;
541     }
542     clientSems = malloc(sizeof(sem_t) * num_threads);
543     if (!clientSems) {
544         free(clientThreads);
545         ret = close(fd);
546         return -1;
547     }
549     readMsg = malloc(sizeof(bool) * num_threads);
550     if (!readMsg) {
551         free(clientSems);
552         free(clientThreads);
553         ret = close(fd);
554         return -1;
555     }
557     clientPackets = malloc(sizeof(char *) * num_threads);
558     if (!clientPackets) {
559         free(readMsg);
560         free(clientSems);
561         free(clientThreads);
562         ret = close(fd);
563         return -1;
564     }
566     for (i = 0; i < num_threads; i++) {
567         clientPackets[i] = malloc(512 * sizeof(char));
568         if (!clientPackets[i]) {
569             for (j = 0; j < i; j++) {
570                 free(clientPackets[j]);
571             }
572             free(clientPackets);
573             free(readMsg);
574             free(clientSems);
575             free(clientThreads);
576             close(fd);
577             return -1;
578         }
579     }
581     ret = pthread_create(&read_thread, NULL, test_read_thread, (void *)fd);
582     if (ret < 0) {
583         perror("Can't create thread");
584         for (i = 0; i < num_threads; i++) {
585             free(clientPackets[i]);
586         }
587         free(clientPackets);
588         free(readMsg);
589         free(clientSems);
590         free(clientThreads);
591         close(fd);
592         return -1;
593     }
595     for ( i = 0; i < num_threads; i++) {
596         ret = sem_init(&clientSems[i], 0, 0);
597         args[i].fd = fd;
598         args[i].start_num = (i * NUM_ITERATIONS) + 1;
599         args[i].test_num = 2;
600         args[i].sem = &clientSems[i];
601         args[i].thread_num = i;
602         readMsg[i] = true;
603         ret = pthread_create(&clientThreads[i], NULL, test_exec_call,
604                              (void *)&args[i]);
605         if (ret < 0) {
606             perror("Can't create thread");
607             ret = -1;
608             break;
609         }
610         printf("Created thread %d\n", i);
611     }
613     for (j = 0; j < i; j++) {
614         printf("Join thread %d\n", j);
615         pthread_join(clientThreads[j], NULL);
616         sem_destroy(&clientSems[j]);
617     }
619     function = (struct rppc_function *)packet_buf;
620     function->fxn_id = FXN_IDX_FXNTRIPLE;
621     function->num_params = 1;
622     function->params[0].type = RPPC_PARAM_TYPE_ATOMIC;
623     function->params[0].size = sizeof(int);
624     function->params[0].data = i;
625     function->num_translations = 0;
627     /* Exec command: */
628     packet_len = sizeof(struct rppc_function) +\
629                  (function->num_translations *\
630                   sizeof(struct rppc_param_translation));
632     runTest = false;
633     if (send_cmd(fd, (char *)packet_buf, packet_len)) {
634         test_status = -1;
635     }
637     pthread_join(read_thread, NULL);
639     for (i = 0; i < num_threads; i++) {
640         free(clientPackets[i]);
641     }
642     free(clientPackets);
643     free(readMsg);
644     free(clientSems);
645     free(clientThreads);
647     /* Terminate connection and destroy rpc_example instance */
648     ret = close(fd);
649     if (ret < 0) {
650         perror("Can't close rpc_example fd ??");
651         ret = -1;
652     }
653     printf("rpc_sample: Closed connection to %s!\n", connreq.name);
655     return ret;
658 int test_rpc_stress_multi_srvmgr(int core_id, int num_comps)
660     int ret = 0;
661     int i = 0, j = 0;
662     int fd[num_comps];
663     struct rppc_create_instance connreq;
664     test_exec_args args[num_comps];
666     for (i = 0; i < num_comps; i++) {
667         /* Connect to the rpc_example ServiceMgr on the specified core: */
668         if (core_id == 0) {
669             fd[i] = open("/dev/rpmsg-omx0", O_RDWR);
670             if (fd[i] < 0) {
671                 perror("Can't open OMX device");
672                 ret = -1;
673                 break;
674             }
675             strcpy(connreq.name, "rpmsg-omx0");
676         }
677         else if (core_id == 1) {
678             fd[i] = open("/dev/rpc_example", O_RDWR);
679             if (fd[i] < 0) {
680                 perror("Can't open rpc_example device");
681                 ret = -1;
682                 break;
683             }
684             strcpy(connreq.name, "rpc_example");
685         }
686         else if (core_id == 2) {
687             fd[i] = open("/dev/rpmsg-omx2", O_RDWR);
688             if (fd[i] < 0) {
689                 perror("Can't open OMX device");
690                 ret = -1;
691                 break;
692             }
693             strcpy(connreq.name, "rpmsg-omx2");
694         }
695         /* Create an rpc_example server instance, and rebind its address to this
696         * file descriptor.
697         */
698         ret = ioctl(fd[i], RPPC_IOC_CREATE, &connreq);
699         if (ret < 0) {
700             perror("Can't connect to rpc_example instance");
701             close(fd[i]);
702             break;
703         }
704         printf("rpc_sample: Connected to %s\n", connreq.name);
705     }
706     if (i != num_comps) {
707         /* cleanup */
708         for (j = 0; j < i; j++) {
709             ret = close(fd[j]);
710             if (ret < 0) {
711                 perror("Can't close rpc_example fd ??");
712             }
713         }
714         return -1;
715     }
717     clientThreads = malloc(sizeof(pthread_t) * num_comps);
718     if (!clientThreads) {
719         for (i = 0; i < num_comps; i++) {
720             ret = close(fd[i]);
721             if (ret < 0) {
722                 perror("Can't close rpc_example fd ??");
723             }
724         }
725         return -1;
726     }
728     for ( i = 0; i < num_comps; i++) {
729         args[i].fd = fd[i];
730         args[i].start_num = 1;
731         args[i].test_num = 1;
732         args[i].sem = NULL;
733         args[i].thread_num = i;
734         ret = pthread_create(&clientThreads[i], NULL, test_exec_call,
735                              (void *)&args[i]);
736         if (ret < 0) {
737             perror("Can't create thread");
738             ret = -1;
739             break;
740         }
741         printf("Created thread %d\n", i);
742     }
744     for (j = 0; j < i; j++) {
745         printf("Join thread %d\n", j);
746         pthread_join(clientThreads[j], NULL);
747     }
749     free(clientThreads);
751     for (i = 0; i < num_comps; i++) {
752         /* Terminate connection and destroy rpc_example instance */
753         ret = close(fd[i]);
754         if (ret < 0) {
755             perror("Can't close rpc_example fd ??");
756             ret = -1;
757         }
758         printf("rpc_sample: Closed connection to %s!\n", connreq.name);
759     }
761     return ret;
764 int main(int argc, char *argv[])
766     int ret;
767     int test_id = -1;
768     int core_id = 0;
769     int num_comps = 1;
770     int num_threads = 1;
771     int c;
773     while (1)
774     {
775         c = getopt (argc, argv, "t:c:x:l:");
776         if (c == -1)
777             break;
779         switch (c)
780         {
781         case 't':
782             test_id = atoi(optarg);
783             break;
784         case 'c':
785             core_id = atoi(optarg);
786             break;
787         case 'x':
788             num_comps = atoi(optarg);
789             break;
790         case 'l':
791             num_threads = atoi(optarg);
792             break;
793         default:
794             printf ("Unrecognized argument\n");
795         }
796     }
798     if (test_id < 0 || test_id > 3) {
799         printf("Invalid test id\n");
800         return 1;
801     }
803     switch (test_id) {
804         case 1:
805             /* multiple threads each with an RPMSG-RPC ServiceMgr instance */
806             if (core_id < 0 || core_id > 2) {
807                 printf("Invalid core id\n");
808                 return 1;
809             }
810             if (num_comps < 0) {
811                 printf("Invalid num comps id\n");
812                 return 1;
813             }
814             ret = test_rpc_stress_multi_srvmgr(core_id, num_comps);
815             break;
816         case 2:
817             /* Multiple threads, 1 RPMSG-RPC ServiceMgr instances */
818             if (core_id < 0 || core_id > 2) {
819                 printf("Invalid core id\n");
820                 return 1;
821             }
822             if (num_threads < 0) {
823                 printf("Invalid num threads\n");
824                 return 1;
825             }
826             ret = test_rpc_stress_multi_threads(core_id, num_threads);
827             break;
828         case 3:
829             /* 1 thread using multiple RPMSG-RPC ServiceMgr instances */
830             if (core_id < 0 || core_id > 2) {
831                 printf("Invalid core id\n");
832                 return 1;
833             }
834             if (num_comps < 0) {
835                 printf("Invalid num comps id\n");
836                 return 1;
837             }
838             ret = test_rpc_stress_select(core_id, num_comps);
839             break;
840         default:
841             break;
842     }
844     if (ret < 0 || test_status < 0) {
845         printf ("TEST STATUS: FAILED.\n");
846     }
847     else {
848         printf ("TEST STATUS: PASSED.\n");
849     }
850     return 0;