All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pradyumna Sampath <pradysam@gmail.com>
To: linux-rt-users@vger.kernel.org
Cc: rachana.rao@in.abb.com
Subject: mq_timedrecieve timeout accuracy
Date: Wed, 24 Mar 2010 13:27:14 +0100	[thread overview]
Message-ID: <6d09081c1003240527r471ee34etbba11b4b7c7e92b3@mail.gmail.com> (raw)

[-- 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 --]

             reply	other threads:[~2010-03-24 12:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-24 12:27 Pradyumna Sampath [this message]
2010-03-24 13:12 ` mq_timedrecieve timeout accuracy 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6d09081c1003240527r471ee34etbba11b4b7c7e92b3@mail.gmail.com \
    --to=pradysam@gmail.com \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=rachana.rao@in.abb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.