1
2 /*
3 * Copyright (c) 2002, Intel Corporation. All rights reserved.
4 * Created by: crystal.xiong REMOVE-THIS AT intel DOT com
5 * This file is licensed under the GPL license. For the full content
6 * of this license, see the COPYING file at the top level of this
7 * source tree.
8 *
9 * Test whether message queue can work correctly under lots of usage.
10 * 1. Many threads sending/receiving on different message queue.
11 * 2. Set different Priority to the messages in the message queue, to see whether the highest priority is received first.
12 */
13
14 #include <stdio.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17 #include <stdlib.h>
18 #include <sys/wait.h>
19 #include <sys/mman.h>
20 #include <string.h>
21 #include <getopt.h>
22 #include <pthread.h>
23 #include <limits.h>
24 #include <mqueue.h>
25
26 #include "posixtest.h"
27
28 #define MSG_SIZE 128
29 #define MAX_MSG 3
30 #define Max_Threads 10
31 #define Name_Size 20
32
33 typedef struct {
34 int ThreadID;
35 mqd_t mqID;
36 } mq_info;
37
msend(void * info)38 static int *msend(void *info)
39 {
40 int i;
41
42 const char *s_msg_ptr[] = { "msg test 1", "msg test 2", "msg test 3" };
43 mq_info send_info;
44 send_info.ThreadID = ((mq_info *) info)->ThreadID;
45 send_info.mqID = ((mq_info *) info)->mqID;
46 printf("Enter into send [%d], mq = %d \n", send_info.ThreadID,
47 send_info.mqID);
48 for (i = 0; i < MAX_MSG; i++) {
49 if (-1 == mq_send(send_info.mqID, s_msg_ptr[i], MSG_SIZE, i)) {
50 perror("mq_send doesn't return success \n");
51 pthread_exit((void *)1);
52 }
53 printf("[%d] send '%s' in thread send [%d]. \n", i + 1,
54 s_msg_ptr[i], send_info.ThreadID);
55 }
56 pthread_exit(NULL);
57
58 }
59
mreceive(void * info)60 static int *mreceive(void *info)
61 {
62 int i;
63 char r_msg_ptr[MAX_MSG][MSG_SIZE];
64
65 mq_info recv_info;
66 recv_info.ThreadID = ((mq_info *) info)->ThreadID;
67 recv_info.mqID = ((mq_info *) info)->mqID;
68 printf("Enter into receive [%d], mq = %d \n", recv_info.ThreadID,
69 recv_info.mqID);
70 for (i = 0; i < MAX_MSG; i++) {
71 if (-1 ==
72 mq_receive(recv_info.mqID, r_msg_ptr[i], MSG_SIZE, NULL)) {
73 perror("mq_receive doesn't return success \n");
74 pthread_exit(NULL);
75 }
76 printf("[%d] receive '%s' in thread receive recv [%d]. \n",
77 i + 1, r_msg_ptr[i], recv_info.ThreadID);
78 }
79
80 pthread_exit(NULL);
81 }
82
main(int argc,char * argv[])83 int main(int argc, char *argv[])
84 {
85 const char *MQ_NAME[Max_Threads] =
86 { "/msg1", "/msg2", "/msg3", "/msg4", "/msg5", "/msg6", "/msg7",
87 "/msg8", "/msg9", "/msg10" };
88 mqd_t mq[Max_Threads];
89 struct mq_attr mqstat;
90 int oflag = O_CREAT | O_NONBLOCK | O_RDWR;
91 int num, i;
92 pthread_t sed[Max_Threads], rev[Max_Threads];
93 mq_info info[Max_Threads];
94
95 /* #ifndef _POSIX_MESSAGE_PASSING
96 printf("_POSIX_MESSAGE_PASSING is not defined \n");
97 return PTS_UNRESOLVED;
98 #endif */
99 if ((2 != argc) || ((num = atoi(argv[1])) <= 0)) {
100 fprintf(stderr, "Usage: %s number_of_threads\n", argv[0]);
101 return PTS_FAIL;
102 }
103 if (num > Max_Threads) {
104 printf("The num of threads are too large. Reset to %d\n",
105 Max_Threads);
106 num = Max_Threads;
107 }
108 memset(&mqstat, 0, sizeof(mqstat));
109 mqstat.mq_maxmsg = MAX_MSG;
110 mqstat.mq_msgsize = MSG_SIZE;
111 mqstat.mq_flags = 0;
112
113 for (i = 0; i < num; i++) {
114 if ((mq[i] = mq_open(MQ_NAME[i], oflag, 0777, &mqstat)) == (mqd_t)-1) {
115 perror("mq_open doesn't return success \n");
116 return PTS_UNRESOLVED;
117 }
118 printf("mq[%i] created \n", i);
119 }
120 for (i = 0; i < num; i++) {
121 info[i].ThreadID = i;
122 info[i].mqID = mq[i];
123 pthread_create(&sed[i], NULL, (void *)msend, (void *)&info[i]);
124 pthread_create(&rev[i], NULL, (void *)mreceive,
125 (void *)&info[i]);
126 }
127 for (i = 0; i < num; i++) {
128 pthread_join(sed[i], NULL);
129 pthread_join(rev[i], NULL);
130 }
131
132 for (i = 0; i < num; i++) {
133 mq_close(mq[i]);
134 mq_close(mq[i]);
135 mq_unlink(MQ_NAME[i]);
136 mq_unlink(MQ_NAME[i]);
137 }
138 return PTS_PASS;
139 }
140