1/*
2 * Copyright (c) 2002, Intel Corporation. All rights reserved.
3 * Created by:  crystal.xiong REMOVE-THIS AT intel DOT com
4 * This file is licensed under the GPL license.  For the full content
5 * of this license, see the COPYING file at the top level of this
6 * source tree.
7 *
8 * Test whether message queue can work correctly under lots of usage.
9 * 1. Many threads sending/receiving on the same message queue.
10 * 2. Set different Priority to the messages in the message queue, to see
11 * 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 MQ_NAME       "/testmsg1"
29#define MSG_SIZE	128
30#define MAX_MSG		5
31#define Max_Threads	100
32
33const char *s_msg_ptr[] = {"send_1 1", "send_1 2", "send_1 3", "send_1 4", "send_1 5"};
34char r_msg_ptr[Max_Threads][MAX_MSG][MSG_SIZE];
35mqd_t mq = 0;
36
37int *send(void * ID)
38{
39	int i;
40	int ThreadID = *(int *)ID;
41
42	printf("Enter into send [%d] \n", ThreadID);
43	for (i = 0; i < MAX_MSG; i++ ) {
44		if ( -1 == mq_send(mq, s_msg_ptr[i], MSG_SIZE, i)) {
45			perror("mq_send doesn't return success \n");
46			pthread_exit((void *)1);
47		}
48		printf("[%d] send '%s' in thread send %d. \n", i+1, s_msg_ptr[i], ThreadID);
49	}
50	pthread_exit((void *)0);
51
52}
53int *receive(void * ID )
54{
55	int i;
56	int ThreadID = *(int *)ID;
57
58	printf("Enter into receive[%d] \n", ThreadID);
59	for (i = 0; i< MAX_MSG; i++) {
60		if ( -1 == mq_receive(mq, r_msg_ptr[ThreadID][i], MSG_SIZE, NULL) ) {
61			perror("mq_receive doesn't return success \n");
62			pthread_exit((void *)1);
63		}
64		printf("[%d] receive '%s' in thread receive[%d]. \n", i+1, r_msg_ptr[ThreadID][i], ThreadID);
65	}
66	printf("receive[%d] quit ...\n", ThreadID);
67	pthread_exit((void *)0);
68}
69int main(int argc, char *argv[])
70{
71
72	struct mq_attr mqstat;
73	int oflag = O_CREAT|O_NONBLOCK|O_RDWR;
74	pthread_t sed[Max_Threads], rev[Max_Threads];
75	int ThreadID[Max_Threads];
76	int num, i;
77
78/* #ifndef  _POSIX_MESSAGE_PASSING
79	printf("_POSIX_MESSAGE_PASSING is not defined \n");
80	return PTS_UNRESOLVED;
81#endif */
82	if ( (2 != argc) || (( num = atoi(argv[1])) <= 0)) {
83		fprintf(stderr, "Usage: %s number_of_threads\n", argv[0]);
84                return PTS_FAIL;
85        }
86	if (num > Max_Threads) {
87        	printf("The num of threads are too large.  Reset to %d\n", Max_Threads);
88        	num = Max_Threads;
89	}
90	memset(&mqstat, 0, sizeof(mqstat));
91	mqstat.mq_maxmsg = MAX_MSG;
92	mqstat.mq_msgsize = MSG_SIZE;
93	mqstat.mq_flags = 0;
94
95  	if( ((mqd_t) -1) == (mq = mq_open(MQ_NAME,oflag,0777, &mqstat)) ) {
96		printf("mq_open doesn't return success \n");
97		return PTS_UNRESOLVED;
98	}
99
100	for (i = 0; i < num; i++) {
101		ThreadID[i] = i;
102		pthread_create(&sed[i], NULL, (void *)send, (void *)&ThreadID[i]);
103       	 	pthread_create(&rev[i], NULL, (void *)receive, (void *)&ThreadID[i]);
104	}
105
106	for (i = 0; i < num; i++) {
107		pthread_join(sed[i], NULL);
108		pthread_join(rev[i], NULL);
109	}
110	mq_close(mq);
111	mq_unlink(MQ_NAME);
112	return PTS_PASS;
113}
114
115