All of lore.kernel.org
 help / color / mirror / Atom feed
* mq_timedrecieve timeout accuracy
@ 2010-03-24 12:27 Pradyumna Sampath
  2010-03-24 13:12 ` John Kacur
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Pradyumna Sampath @ 2010-03-24 12:27 UTC (permalink / raw)
  To: linux-rt-users; +Cc: rachana.rao

[-- Attachment #1: Type: text/plain, Size: 1481 bytes --]

Hi,

We are dealing with an application that is a fairly heavy user of
POSIX message queues. While running this application I seemed to have
stumbled upon the fact that the timeout in the mq_timedrecieve is
innaccurate to the tune of a more than 5-6 miliseconds and that it is
fairly consistent even at its highest priority.

Cyclictest on the same machine gives me a max deviation of about 7uS,
so I guess my timers (hrt) are functioning alright.

Here is a small program I hacked up from the LTP sources to
demonstrate this behaviour (attached). I ran this on a dual core
2.5Ghz cpu and a uniprocessor 1.5Ghz cpu (cpuinfo below). On the
dual-core I can see that its off by 1-2 miliseconds but on the 1.5 Ghz
celeron its off by 6-8 miliseconds sometimes.

kernel version: 2.6.33.1-rt10

Usage: ./send_rev_2 <timeout_in_miliseconds>

$ cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 13
model name      : Intel(R) Celeron(R) M processor         1.50GHz
stepping        : 8
cpu MHz         : 1500.111
cache size      : 1024 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov
clflush dts acpi mmx fxsr sse sse2 ss tm pbe nx up bts

Also attaached is my .config.

thanks in advance
regards
/prady


-- 
http://www.prady.in

[-- Attachment #2: send_rev_2.c --]
[-- Type: text/plain, Size: 4402 bytes --]


/*   
 * Copyright (c) 2002, Intel Corporation. All rights reserved.
 * Created by:  crystal.xiong REMOVE-THIS AT intel DOT com
 * This file is licensed under the GPL license.  For the full content
 * of this license, see the COPYING file at the top level of this 
 * source tree.
 * 
 * 1. Two threads sending/receiving on different message queue.
 * 2. Set different Priority to the messages in the message queue, to 
 * see whether the highest priority is received first.
 */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <string.h>
#include <getopt.h>
#include <pthread.h>
#include <limits.h>
#include <mqueue.h>
#include <time.h>
#include <errno.h>

#include "posixtest.h"

#define MQ_NAME_1       "/testmsg1"
#define MQ_NAME_2       "/testmsg2"
#define MSG_SIZE	128
#define MAX_MSG		3
#define MSEC_PER_SEC 1000
#define NSEC_PER_SEC 1000000000

const char *s_msg_ptr[] = {"msg test 1", "msg test 2", "msg test 3"};
char r_msg_ptr_1[MAX_MSG][MSG_SIZE];
char r_msg_ptr_2[MAX_MSG][MSG_SIZE];
pthread_t send1, send2, rev1, rev2;
long timeout; 

int * send_1(void * mq) 
{
	int i;
	mqd_t mq1 = *(mqd_t *)mq;

	printf("Enter into send_1 \n");
	for (i = 0; i < MAX_MSG; i++ ) {
		sleep(1);
		if ( -1 == mq_send(mq1, s_msg_ptr[i], MSG_SIZE, i)) {
			perror("mq_send doesn't return success \n");
			pthread_exit((void *)1);
		}
		printf("[%d] send '%s' in thread send_1. \n", i+1, s_msg_ptr[i]);
	}
	pthread_exit((void *)0);

}
int * send_2(void * mq) 
{
	int i;
 	mqd_t mq2 = *(mqd_t *)mq;

	printf("Enter into send_2 \n");
	for (i = 0; i < MAX_MSG; i++ ) {
		if ( -1 == mq_send(mq2, s_msg_ptr[i], MSG_SIZE, i)) {
			perror("mq_send doesn't return success \n");
			pthread_exit((void *)1);
		}
		printf("[%d] send '%s' in thread send_2. \n", i+1, s_msg_ptr[i]);
	}
	pthread_exit((void *)0);
}
int * receive_1(void * mq) 
{
	int i;
	mqd_t mq1 = *(mqd_t *)mq;
	struct timespec ts,ts_start,ts_end;
	long diff_sec, diff_nsec;

	printf("Enter into receive_1 \n");
	while(1) {

			clock_gettime(CLOCK_REALTIME, &ts);
			ts.tv_sec+= (long int)timeout  / MSEC_PER_SEC;
			ts.tv_nsec+=( (long int)timeout % MSEC_PER_SEC) * 1000000;
			while (ts.tv_nsec >=NSEC_PER_SEC)
			{
				ts.tv_nsec -=NSEC_PER_SEC;
				ts.tv_sec++;
			}
	
			clock_gettime(CLOCK_REALTIME,&ts_start);
			if (mq_timedreceive(mq1, r_msg_ptr_1[i], MSG_SIZE, NULL,&ts) < 0)  {
				perror("mq_receive1");
				//pthread_exit((void *)1);
			}
			clock_gettime(CLOCK_REALTIME,&ts_end);
			diff_sec = ts_end.tv_sec - ts_start.tv_sec ;
			diff_nsec = ts_end.tv_nsec - ts_start.tv_nsec;
			//printf("[%d] receive '%s' in thread receive_1. %ld %ld \n", i+1, r_msg_ptr_1[i],diff_sec, diff_nsec);
			printf("%ld %ld \n", diff_sec, diff_nsec);
	}
	//pthread_exit((void *)0);
}
int * receive_2(void * mq) 
{
	int i;
	mqd_t mq2 = *(mqd_t *)mq;

	printf("Enter into receive_2 \n");
	for (i = 0; i< MAX_MSG; i++) {
		if ( -1 == mq_receive(mq2, r_msg_ptr_2[i], MSG_SIZE, NULL) ) {
			perror("mq_receive doesn't return success \n");
			pthread_exit((void *)1);
		}
		printf("[%d] receive '%s' in thread receive_2. \n", i+1, r_msg_ptr_2[i]);
	}
	pthread_exit((void *)0);
}
int main(int argc, char *argv[])
{
	
 	mqd_t mq1 = 0, mq2 = 0;	
	struct mq_attr mqstat;
	int oflag = O_CREAT|O_RDWR;
	timeout = atoi(argv[1]);
	memset(&mqstat, 0, sizeof(mqstat));
	mqstat.mq_maxmsg = MAX_MSG;
	mqstat.mq_msgsize = MSG_SIZE;
	mqstat.mq_flags = 0;
  
  	if( ((mqd_t) -1) == (mq1 = mq_open(MQ_NAME_1,oflag,0777, &mqstat)) ) {
		printf("mq_open doesn't return success \n");
		return PTS_UNRESOLVED;
	}
  	if( ((mqd_t) -1) == (mq2 = mq_open(MQ_NAME_2,oflag,0777, &mqstat)) ) {
		printf("mq_open doesn't return success \n");
		return PTS_UNRESOLVED;
	}
	pthread_create(&send1, NULL, (void *)send_1, (void *)&mq1);
//	pthread_create(&send2, NULL, (void *)send_2, (void *)&mq2);
        pthread_create(&rev1, NULL, (void *)receive_1, (void *)&mq1);	
//        pthread_create(&rev2, NULL, (void *)receive_2, (void *)&mq2);	
	pthread_join(send1, NULL);
//	pthread_join(send2, NULL);
	pthread_join(rev1, NULL);
//	pthread_join(rev2, NULL);
		
	mq_close(mq1);
	mq_close(mq2);
	mq_unlink(MQ_NAME_1);
	mq_unlink(MQ_NAME_2);
	return PTS_PASS;
}


[-- Attachment #3: .config --]
[-- Type: application/xml, Size: 28757 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2010-03-30  7:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-24 12:27 mq_timedrecieve timeout accuracy Pradyumna Sampath
2010-03-24 13:12 ` John Kacur
2010-03-24 13:21 ` Sujit K M
2010-03-24 13:22 ` M. Koehrer
2010-03-24 13:37   ` Pradyumna Sampath
2010-03-24 13:45     ` Sujit K M
2010-03-24 13:47       ` Pradyumna Sampath
2010-03-24 14:03     ` Pradyumna Sampath
2010-03-24 15:46       ` [PATCH] " Pradyumna Sampath
2010-03-29 15:08         ` [PATCH] " Carsten Emde
2010-03-30  7:41           ` Pradyumna Sampath

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.