• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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