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

* Re: mq_timedrecieve timeout accuracy
  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
  2 siblings, 0 replies; 11+ messages in thread
From: John Kacur @ 2010-03-24 13:12 UTC (permalink / raw)
  To: Pradyumna Sampath; +Cc: linux-rt-users, rachana.rao

On Wed, Mar 24, 2010 at 1:27 PM, Pradyumna Sampath <pradysam@gmail.com> wrote:
> 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
>
>

Could you try using CLOCK_MONOTONIC instead of CLOCK_REALTIME in the
clock_gettime() call?

CLOCK_REALTIME isn't actually for real-time, it is the "real" time, which can be
adjusted if you sync with ntp servers for example.
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: mq_timedrecieve timeout accuracy
  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
  2 siblings, 0 replies; 11+ messages in thread
From: Sujit K M @ 2010-03-24 13:21 UTC (permalink / raw)
  To: Pradyumna Sampath; +Cc: linux-rt-users, rachana.rao

> 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.

OK.

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

Out of how much? What is the range of the timer.

> 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.

Yes, but the cyclic test doesnot match with this result. Both are in
the negative.
How have you tested the patch.

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



-- 
-- Sujit K M

blog(http://kmsujit.blogspot.com/)
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: mq_timedrecieve timeout accuracy
  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
  2 siblings, 1 reply; 11+ messages in thread
From: M. Koehrer @ 2010-03-24 13:22 UTC (permalink / raw)
  To: pradysam, linux-rt-users; +Cc: rachana.rao

> 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
Does it help to run the posix threads with realtime priority by calling
pthread_setschedparam() with SCHED_FIFO and a suitable priority?
As fas as I understand your code, the threads run with standard (non realtime
priority).


Mathias



-- 
Mathias Koehrer
mathias_koehrer@arcor.de


Holt sich Schumi den 8. Titel seiner Formel-1-Karriere? Schumi reloaded, alle Infos, Fahrer- und Team-Portraits und das Formel-1-Experten-Quiz finden Sie hier: http://www.arcor.de/rd/footer.f1

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

* Re: mq_timedrecieve timeout accuracy
  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 14:03     ` Pradyumna Sampath
  0 siblings, 2 replies; 11+ messages in thread
From: Pradyumna Sampath @ 2010-03-24 13:37 UTC (permalink / raw)
  To: M. Koehrer; +Cc: linux-rt-users, rachana.rao

Hi,

On Wed, Mar 24, 2010 at 2:22 PM, M. Koehrer <mathias_koehrer@arcor.de> wrote:
> Does it help to run the posix threads with realtime priority by calling
> pthread_setschedparam() with SCHED_FIFO and a suitable priority?
> As fas as I understand your code, the threads run with standard (non realtime
> priority).

Yes. I tried this with a chrt -f 99. But I still end up getting those
large deviations.

John, mq_timedrecieve takes abstime. Isnt it supposed to be
CLOCK_REALTIME ? Anyway, I tried with MONOTONIC .. mq_timedrecieve
doesnt block on that.

I was just looking at some code in the kernel. linux/ipc/mqueue.c
+442. This line says:

time = schedule_timeout(timeout);

Maybe this is why produces a timeout that is inaccurate. Shouldnt it
be schedule_hrtimeout ?

regards
/prady

--
http://www.prady.in

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

* Re: mq_timedrecieve timeout accuracy
  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
  1 sibling, 1 reply; 11+ messages in thread
From: Sujit K M @ 2010-03-24 13:45 UTC (permalink / raw)
  To: Pradyumna Sampath; +Cc: M. Koehrer, linux-rt-users, rachana.rao

> time = schedule_timeout(timeout);
Fine.

> Maybe this is why produces a timeout that is inaccurate. Shouldnt it
> be schedule_hrtimeout ?

Does the RT Patch change anything. OR is it the same.

>
> regards
> /prady
>
> --
> http://www.prady.in
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
-- Sujit K M

blog(http://kmsujit.blogspot.com/)
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: mq_timedrecieve timeout accuracy
  2010-03-24 13:45     ` Sujit K M
@ 2010-03-24 13:47       ` Pradyumna Sampath
  0 siblings, 0 replies; 11+ messages in thread
From: Pradyumna Sampath @ 2010-03-24 13:47 UTC (permalink / raw)
  To: Sujit K M; +Cc: M. Koehrer, linux-rt-users, rachana.rao

On Wed, Mar 24, 2010 at 2:45 PM, Sujit K M <sjt.kar@gmail.com> wrote:

> Fine.
>
>> Maybe this is why produces a timeout that is inaccurate. Shouldnt it
>> be schedule_hrtimeout ?
>
> Does the RT Patch change anything. OR is it the same.
>

I dont have a vanilla kernel on this piece of hardware. But, I would
guess these numbers are not really expected out of the RT_PREEMPT
kernel ? Im not sure if anyone has run any kind of benchmarks with
ipc's .. message queues in particular.

regards
/prady

-- 
http://www.prady.in

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

* Re: mq_timedrecieve timeout accuracy
  2010-03-24 13:37   ` Pradyumna Sampath
  2010-03-24 13:45     ` Sujit K M
@ 2010-03-24 14:03     ` Pradyumna Sampath
  2010-03-24 15:46       ` [PATCH] " Pradyumna Sampath
  1 sibling, 1 reply; 11+ messages in thread
From: Pradyumna Sampath @ 2010-03-24 14:03 UTC (permalink / raw)
  To: M. Koehrer; +Cc: linux-rt-users, rachana.rao

Hi,

On Wed, Mar 24, 2010 at 2:37 PM, Pradyumna Sampath <pradysam@gmail.com> wrote:
> John, mq_timedrecieve takes abstime. Isnt it supposed to be
> CLOCK_REALTIME ? Anyway, I tried with MONOTONIC .. mq_timedrecieve
> doesnt block on that.
>
> I was just looking at some code in the kernel. linux/ipc/mqueue.c
> +442. This line says:
>
> time = schedule_timeout(timeout);
>
> Maybe this is why produces a timeout that is inaccurate. Shouldnt it
> be schedule_hrtimeout ?

Ok, I just moved the HZ value from 250 to 1000 and the accuracy has
improved significantly from 5-7 to 1-2 miliseconds. But IMHO, we
should still change schedule_timeout to schedule_hrtimeout for better
accuracy on the timeout because in many cases 1-2 miliseconds is just
not good enough.

I will try to push out a patch for this later today.

regards
/prady

-- 
http://www.prady.in

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

* Re: [PATCH] mq_timedrecieve timeout accuracy
  2010-03-24 14:03     ` Pradyumna Sampath
@ 2010-03-24 15:46       ` Pradyumna Sampath
  2010-03-29 15:08         ` [PATCH] " Carsten Emde
  0 siblings, 1 reply; 11+ messages in thread
From: Pradyumna Sampath @ 2010-03-24 15:46 UTC (permalink / raw)
  To: M. Koehrer; +Cc: linux-rt-users, rachana.rao

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

Hi,

On Wed, Mar 24, 2010 at 3:03 PM, Pradyumna Sampath <pradysam@gmail.com> wrote:
> Ok, I just moved the HZ value from 250 to 1000 and the accuracy has
> improved significantly from 5-7 to 1-2 miliseconds. But IMHO, we
> should still change schedule_timeout to schedule_hrtimeout for better
> accuracy on the timeout because in many cases 1-2 miliseconds is just
> not good enough.

Ok, as promised.

Here is a dirty hack that I made which basically resulted in 2 things.
1) My test programs accurace really really improved. The timeout on
the mq_timedrecieve this time around within the tune of 20-30uS.
2) My actual application exploded all over the place, with mq_*
functions complaining of timing out etc etc .. Just a bad messup.

So (1) confirms that sched_hrtimeout could be a good idea. (2)
Confirms that this patch is really terrible and it would be great if
someone could either come up with something that is more robust or I
will be happy to take suggestions on where and how I should make
changes.

regards
/prady

-- 
http://www.prady.in

[-- Attachment #2: ipc_mqueue_timeout_to_hrtimeout --]
[-- Type: application/octet-stream, Size: 2002 bytes --]

Index: linux-2.6.33.1-rt10/ipc/mqueue.c
===================================================================
--- linux-2.6.33.1-rt10/ipc/mqueue.c	(revision 801)
+++ linux-2.6.33.1-rt10/ipc/mqueue.c	(working copy)
@@ -428,10 +428,12 @@
  * sr: SEND or RECV
  */
 static int wq_sleep(struct mqueue_inode_info *info, int sr,
-			long timeout, struct ext_wait_queue *ewp)
+			struct timespec timeout, struct ext_wait_queue *ewp)
 {
 	int retval;
 	signed long time;
+	ktime_t expire = timespec_to_ktime(timeout);
+	//printk("timeout = %ld %ld\n",timeout.tv_sec, timeout.tv_nsec);
 
 	wq_add(info, sr, ewp);
 
@@ -439,7 +441,8 @@
 		set_current_state(TASK_INTERRUPTIBLE);
 
 		spin_unlock(&info->lock);
-		time = schedule_timeout(timeout);
+		//time = schedule_timeout(timeout);
+		time = schedule_hrtimeout(&expire,HRTIMER_MODE_REL);
 
 		while (ewp->state == STATE_PENDING)
 			cpu_relax();
@@ -864,6 +867,7 @@
 	long timeout;
 	int ret;
 
+
 	if (u_abs_timeout) {
 		if (copy_from_user(&ts, u_abs_timeout, 
 					sizeof(struct timespec)))
@@ -919,7 +923,8 @@
 			wait.task = current;
 			wait.msg = (void *) msg_ptr;
 			wait.state = STATE_NONE;
-			ret = wq_sleep(info, SEND, timeout, &wait);
+			//ret = wq_sleep(info, SEND, timeout, &wait);
+			ret = wq_sleep(info, SEND, ts, &wait);
 		}
 		if (ret < 0)
 			free_msg(msg_ptr);
@@ -956,6 +961,7 @@
 	struct ext_wait_queue wait;
 	struct timespec ts, *p = NULL;
 
+
 	if (u_abs_timeout) {
 		if (copy_from_user(&ts, u_abs_timeout, 
 					sizeof(struct timespec)))
@@ -966,6 +972,7 @@
 	audit_mq_sendrecv(mqdes, msg_len, 0, p);
 	timeout = prepare_timeout(p);
 
+	//printk("timedrecieve = %ld %ld\n",ts.tv_sec, ts.tv_nsec);
 	ret = -EBADF;
 	filp = fget(mqdes);
 	if (unlikely(!filp))
@@ -999,7 +1006,8 @@
 		} else {
 			wait.task = current;
 			wait.state = STATE_NONE;
-			ret = wq_sleep(info, RECV, timeout, &wait);
+			//ret = wq_sleep(info, RECV, timeout, &wait);
+			ret = wq_sleep(info, RECV, ts, &wait);
 			msg_ptr = wait.msg;
 		}
 	} else {


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

* [PATCH] Re: mq_timedrecieve timeout accuracy
  2010-03-24 15:46       ` [PATCH] " Pradyumna Sampath
@ 2010-03-29 15:08         ` Carsten Emde
  2010-03-30  7:41           ` Pradyumna Sampath
  0 siblings, 1 reply; 11+ messages in thread
From: Carsten Emde @ 2010-03-29 15:08 UTC (permalink / raw)
  To: Pradyumna Sampath
  Cc: M. Koehrer, linux-rt-users, rachana.rao, Thomas Gleixner

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

Hi Prady,

> [..] Ok, as promised.
> 
> Here is a dirty hack that I made which basically resulted in 2 things.
> 1) My test programs accurace really really improved. The timeout on
> the mq_timedrecieve this time around within the tune of 20-30uS.
> 2) My actual application exploded all over the place, with mq_*
> functions complaining of timing out etc etc .. Just a bad messup.
> 
> So (1) confirms that sched_hrtimeout could be a good idea. (2)
> Confirms that this patch is really terrible and it would be great if
> someone could either come up with something that is more robust or I
> will be happy to take suggestions on where and how I should make
> changes.
Does the attached patch work for you?

- Fixed error handling
- Replaced schedule_timeout() with schedule_hrtimeout()
- Let schedule_hrtimeout() handle expired timers

Signed-off-by: Carsten Emde <C.Emde@osadl.org>

[-- Attachment #2: fix-mqueue-and-use-hrtimer.patch --]
[-- Type: text/x-patch, Size: 3606 bytes --]

--- ipc/mqueue-orig.c	2010-03-29 13:59:14.410923036 +0200
+++ ipc/mqueue.c	2010-03-29 16:38:51.650616863 +0200
@@ -428,10 +428,16 @@
  * sr: SEND or RECV
  */
 static int wq_sleep(struct mqueue_inode_info *info, int sr,
-			long timeout, struct ext_wait_queue *ewp)
+			struct timespec *timeout, struct ext_wait_queue *ewp)
 {
 	int retval;
 	signed long time;
+	ktime_t *expires = NULL, to;
+
+	if (timeout != NULL) {
+		to = timespec_to_ktime(*timeout);
+		expires = &to;
+	}
 
 	wq_add(info, sr, ewp);
 
@@ -439,7 +445,7 @@
 		set_current_state(TASK_INTERRUPTIBLE);
 
 		spin_unlock(&info->lock);
-		time = schedule_timeout(timeout);
+		time = schedule_hrtimeout(expires, HRTIMER_MODE_ABS);
 
 		while (ewp->state == STATE_PENDING)
 			cpu_relax();
@@ -551,33 +557,6 @@
 	wake_up(&info->wait_q);
 }
 
-static long prepare_timeout(struct timespec *p)
-{
-	struct timespec nowts;
-	long timeout;
-
-	if (p) {
-		if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0
-			|| p->tv_nsec >= NSEC_PER_SEC))
-			return -EINVAL;
-		nowts = CURRENT_TIME;
-		/* first subtract as jiffies can't be too big */
-		p->tv_sec -= nowts.tv_sec;
-		if (p->tv_nsec < nowts.tv_nsec) {
-			p->tv_nsec += NSEC_PER_SEC;
-			p->tv_sec--;
-		}
-		p->tv_nsec -= nowts.tv_nsec;
-		if (p->tv_sec < 0)
-			return 0;
-
-		timeout = timespec_to_jiffies(p) + 1;
-	} else
-		return MAX_SCHEDULE_TIMEOUT;
-
-	return timeout;
-}
-
 static void remove_notification(struct mqueue_inode_info *info)
 {
 	if (info->notify_owner != NULL &&
@@ -861,7 +840,6 @@
 	struct msg_msg *msg_ptr;
 	struct mqueue_inode_info *info;
 	struct timespec ts, *p = NULL;
-	long timeout;
 	int ret;
 
 	if (u_abs_timeout) {
@@ -875,7 +853,6 @@
 		return -EINVAL;
 
 	audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
-	timeout = prepare_timeout(p);
 
 	ret = -EBADF;
 	filp = fget(mqdes);
@@ -912,14 +889,17 @@
 		if (filp->f_flags & O_NONBLOCK) {
 			spin_unlock(&info->lock);
 			ret = -EAGAIN;
-		} else if (unlikely(timeout < 0)) {
-			spin_unlock(&info->lock);
-			ret = timeout;
 		} else {
-			wait.task = current;
-			wait.msg = (void *) msg_ptr;
-			wait.state = STATE_NONE;
-			ret = wq_sleep(info, SEND, timeout, &wait);
+			if (p && unlikely(ts.tv_nsec < 0 || ts.tv_sec < 0 ||
+			    ts.tv_nsec >= NSEC_PER_SEC)) {
+				spin_unlock(&info->lock);
+                	        ret = -EINVAL;
+			} else {
+				wait.task = current;
+				wait.msg = (void *) msg_ptr;
+				wait.state = STATE_NONE;
+				ret = wq_sleep(info, SEND, p, &wait);
+			}
 		}
 		if (ret < 0)
 			free_msg(msg_ptr);
@@ -947,7 +927,6 @@
 		size_t, msg_len, unsigned int __user *, u_msg_prio,
 		const struct timespec __user *, u_abs_timeout)
 {
-	long timeout;
 	ssize_t ret;
 	struct msg_msg *msg_ptr;
 	struct file *filp;
@@ -964,7 +943,6 @@
 	}
 
 	audit_mq_sendrecv(mqdes, msg_len, 0, p);
-	timeout = prepare_timeout(p);
 
 	ret = -EBADF;
 	filp = fget(mqdes);
@@ -991,16 +969,17 @@
 		if (filp->f_flags & O_NONBLOCK) {
 			spin_unlock(&info->lock);
 			ret = -EAGAIN;
-			msg_ptr = NULL;
-		} else if (unlikely(timeout < 0)) {
-			spin_unlock(&info->lock);
-			ret = timeout;
-			msg_ptr = NULL;
 		} else {
-			wait.task = current;
-			wait.state = STATE_NONE;
-			ret = wq_sleep(info, RECV, timeout, &wait);
-			msg_ptr = wait.msg;
+			if (p && unlikely(ts.tv_nsec < 0 || ts.tv_sec < 0 ||
+			    ts.tv_nsec >= NSEC_PER_SEC)) {
+				spin_unlock(&info->lock);
+                	        ret = -EINVAL;
+			} else {
+				wait.task = current;
+				wait.state = STATE_NONE;
+				ret = wq_sleep(info, RECV, p, &wait);
+				msg_ptr = wait.msg;
+			}
 		}
 	} else {
 		msg_ptr = msg_get(info);

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

* Re: [PATCH] Re: mq_timedrecieve timeout accuracy
  2010-03-29 15:08         ` [PATCH] " Carsten Emde
@ 2010-03-30  7:41           ` Pradyumna Sampath
  0 siblings, 0 replies; 11+ messages in thread
From: Pradyumna Sampath @ 2010-03-30  7:41 UTC (permalink / raw)
  To: Carsten Emde; +Cc: M. Koehrer, linux-rt-users, rachana.rao, Thomas Gleixner

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

Hi Carsten,

On Mon, Mar 29, 2010 at 5:08 PM, Carsten Emde <Carsten.Emde@osadl.org> wrote:
> Does the attached patch work for you?
>
> - Fixed error handling
> - Replaced schedule_timeout() with schedule_hrtimeout()
> - Let schedule_hrtimeout() handle expired timers

Well no, the mq_timedrecieve blocks for ever using my test program.
This behaviour would not really be evident in the pmqtest since the
frequency of sending the test messages is lesser than the timeout
value.

So, I have modified the pmqtest (attached) to
- Not send test messages

This means when the -T1 option is used it should wait on
mq_timedrecieve for 1 second and then exit. On a normal kernel this
behaviour is demostrated but with the patch on, the timeout never
expires and hence the program does not exit.

regards
/prady

-- 
http://www.prady.in

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

/*
 * pmqtest.c
 *
 * Copyright (C) 2009 Carsten Emde <C.Emde@osadl.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
 * USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/unistd.h>
#include <utmpx.h>
#include <mqueue.h>
#include "rt-utils.h"
#include "rt-get_cpu.h"

#include <pthread.h>

#define gettid() syscall(__NR_gettid)

#define USEC_PER_SEC 1000000

#define SYNCMQ_NAME "/syncmsg%d"
#define TESTMQ_NAME "/testmsg%d"
#define MSG_SIZE 8
#define MSEC_PER_SEC 1000
#define NSEC_PER_SEC 1000000000

char *syncmsg = "Syncing";
char *testmsg = "Testing";

enum {
	AFFINITY_UNSPECIFIED,
	AFFINITY_SPECIFIED,
	AFFINITY_USEALL
};

struct params {
	int num;
	int cpu;
	int priority;
	int affinity;
	int sender;
	int samples;
	int max_cycles;
	int tracelimit;
	int tid;
	int shutdown;
	int stopped;
	struct timespec delay;
	unsigned int mindiff, maxdiff;
	double sumdiff;
	struct timeval sent, received, diff;
	pthread_t threadid;
	int timeout;
	mqd_t syncmq, testmq;
	char recvsyncmsg[MSG_SIZE];
	char recvtestmsg[MSG_SIZE];
	struct params *neighbor;
	char error[MAX_PATH * 2];
};

int no_send = 1;

void *pmqthread(void *param)
{
	int mustgetcpu = 0;
	struct params *par = param;
	cpu_set_t mask;
	int policy = SCHED_FIFO;
	struct sched_param schedp;
	struct timespec ts;

	memset(&schedp, 0, sizeof(schedp));
	schedp.sched_priority = par->priority;
	sched_setscheduler(0, policy, &schedp);

	if (par->cpu != -1) {
		CPU_ZERO(&mask);
		CPU_SET(par->cpu, &mask);
		if(sched_setaffinity(0, sizeof(mask), &mask) == -1)
			fprintf(stderr,	"WARNING: Could not set CPU affinity "
				"to CPU #%d\n", par->cpu);
	} else
		mustgetcpu = 1;

	par->tid = gettid();

	if (par->timeout > 0) {
		clock_gettime(CLOCK_REALTIME, &ts);
		ts.tv_sec += par->timeout;
	}

	while (!par->shutdown) {
		if (par->sender) {
			/* Send message: Start of latency measurement ... */
			gettimeofday(&par->sent, NULL);
			if (mq_send(par->testmq, testmsg, strlen(testmsg), 1) != 0) {
				fprintf(stderr, "could not send test message\n");
				par->shutdown = 1;
			}
			par->samples++;
			if(par->max_cycles && par->samples >= par->max_cycles)
				par->shutdown = 1;
			if (mustgetcpu)
				par->cpu = get_cpu();
			/* Wait until receiver ready */
			if (par->timeout > 0) {
				if (mq_timedreceive(par->syncmq, par->recvsyncmsg, MSG_SIZE, NULL, &ts)
				    != strlen(syncmsg)) {
					fprintf(stderr, "could not receive sync message\n");
					par->shutdown = 1;
				}
			} else {
				if (mq_receive(par->syncmq, par->recvsyncmsg, MSG_SIZE, NULL) !=
				    strlen(syncmsg)) {
					fprintf(stderr, "could not receive sync message\n");
					par->shutdown = 1;
				}
			}
			if (strcmp(syncmsg, par->recvsyncmsg)) {
				fprintf(stderr, "ERROR: Sync message mismatch detected\n");
				fprintf(stderr, "  %s != %s\n", syncmsg, par->recvsyncmsg);
				par->shutdown = 1;
			}

		} else {
			/* Receiver */
			if (par->timeout > 0) {
				if (mq_timedreceive(par->testmq, par->recvtestmsg, MSG_SIZE, NULL, &ts) !=
				    strlen(testmsg)) {
					fprintf(stderr, "could not receive test message\n");
					par->shutdown = 1;
				}
			} else {
				if (mq_receive(par->testmq, par->recvtestmsg, MSG_SIZE, NULL) !=
				    strlen(testmsg)) {
					fprintf(stderr, "could not receive test message\n");
					par->shutdown = 1;
				}
			}
			/* ... Received the message: End of latency measurement */
			gettimeofday(&par->received, NULL);

			if (strcmp(testmsg, par->recvtestmsg)) {
				fprintf(stderr, "ERROR: Test message mismatch detected\n");
				fprintf(stderr, "  %s != %s\n", testmsg, par->recvtestmsg);
				par->shutdown = 1;
			}
			par->samples++;
			timersub(&par->received, &par->neighbor->sent,
			    &par->diff);

			if (par->diff.tv_usec < par->mindiff)
				par->mindiff = par->diff.tv_usec;
			if (par->diff.tv_usec > par->maxdiff)
				par->maxdiff = par->diff.tv_usec;
			par->sumdiff += (double) par->diff.tv_usec;
			if (par->tracelimit && par->maxdiff > par->tracelimit) {
				char tracing_enabled_file[MAX_PATH];

				strcpy(tracing_enabled_file, get_debugfileprefix());
				strcat(tracing_enabled_file, "tracing_enabled");
				int tracing_enabled =
				    open(tracing_enabled_file, O_WRONLY);
				if (tracing_enabled >= 0) {
					write(tracing_enabled, "0", 1);
					close(tracing_enabled);
				} else
					snprintf(par->error, sizeof(par->error),
					    "Could not access %s\n",
					    tracing_enabled_file);
				par->shutdown = 1;
				par->neighbor->shutdown = 1;
			}

			if (par->max_cycles && par->samples >= par->max_cycles)
				par->shutdown = 1;
			if (mustgetcpu)
				par->cpu = get_cpu();
			nanosleep(&par->delay, NULL);

			/* Tell receiver that we are ready for the next measurement */
			if (no_send == 1)
			{
				if (mq_send(par->syncmq, syncmsg, strlen(syncmsg), 1) != 0) {
					fprintf(stderr, "could not send sync message\n");
					par->shutdown = 1;
				}
			}
		}
	}
	par->stopped = 1;
	return NULL;
}


static void display_help(void)
{
	printf("pmqtest V %1.2f\n", VERSION_STRING);
	puts("Usage: pmqtest <options>");
	puts("Function: test POSIX message queue latency");
	puts(
	"Options:\n"
	"-a [NUM] --affinity        run thread #N on processor #N, if possible\n"
	"                           with NUM pin all threads to the processor NUM\n"
	"-b USEC  --breaktrace=USEC send break trace command when latency > USEC\n"
	"-d DIST  --distance=DIST   distance of thread intervals in us default=500\n"
	"-i INTV  --interval=INTV   base interval of thread in us default=1000\n"
	"-l LOOPS --loops=LOOPS     number of loops: default=0(endless)\n"
	"-p PRIO  --prio=PRIO       priority\n"
	"-S       --smp             SMP testing: options -a -t and same priority\n"
        "                           of all threads\n"
	"-t       --threads         one thread per available processor\n"
	"-t [NUM] --threads=NUM     number of threads:\n"
	"                           without NUM, threads = max_cpus\n"
	"                           without -t default = 1\n"
	"-T TO    --timeout=TO      use mq_timedreceive() instead of mq_receive()\n"
	"                           with timeout TO in seconds\n");
	exit(1);
}


static int setaffinity = AFFINITY_UNSPECIFIED;
static int affinity;
static int tracelimit;
static int priority;
static int num_threads = 1;
static int max_cycles;
static int interval = 1000;
static int distance = 500;
static int smp;
static int sameprio;
static int timeout;

static void process_options (int argc, char *argv[])
{
	int error = 0;
	int max_cpus = sysconf(_SC_NPROCESSORS_CONF);

	for (;;) {
		int option_index = 0;
		/** Options for getopt */
		static struct option long_options[] = {
			{"affinity", optional_argument, NULL, 'a'},
			{"breaktrace", required_argument, NULL, 'b'},
			{"distance", required_argument, NULL, 'd'},
			{"interval", required_argument, NULL, 'i'},
			{"loops", required_argument, NULL, 'l'},
			{"priority", required_argument, NULL, 'p'},
			{"smp", no_argument, NULL, 'S'},
			{"threads", optional_argument, NULL, 't'},
			{"timeout", required_argument, NULL, 'T'},
			{"help", no_argument, NULL, '?'},
			{NULL, 0, NULL, 0}
		};
		int c = getopt_long (argc, argv, "a::b:d:i:l:p:St::T:",
			long_options, &option_index);
		if (c == -1)
			break;
		switch (c) {
		case 'a':
			if (smp) {
				warn("-a ignored due to --smp\n");
				break;
			}
			if (optarg != NULL) {
				affinity = atoi(optarg);
				setaffinity = AFFINITY_SPECIFIED;
			} else if (optind<argc && atoi(argv[optind])) {
				affinity = atoi(argv[optind]);
				setaffinity = AFFINITY_SPECIFIED;
			} else {
				setaffinity = AFFINITY_USEALL;
			}
			break;
		case 'b': tracelimit = atoi(optarg); break;
		case 'd': distance = atoi(optarg); break;
		case 'i': interval = atoi(optarg); break;
		case 'l': max_cycles = atoi(optarg); break;
		case 'p': priority = atoi(optarg); break;
		case 'S':
			smp = 1;
			num_threads = max_cpus;
			setaffinity = AFFINITY_USEALL;
			break;
		case 't':
			if (smp) {
				warn("-t ignored due to --smp\n");
				break;
			}
			if (optarg != NULL)
				num_threads = atoi(optarg);
			else if (optind<argc && atoi(argv[optind]))
				num_threads = atoi(argv[optind]);
			else
				num_threads = max_cpus;
			break;
		case 'T': timeout = atoi(optarg); break;
		case '?': error = 1; break;
		}
	}

	if (setaffinity == AFFINITY_SPECIFIED) {
		if (affinity < 0)
			error = 1;
		if (affinity >= max_cpus) {
			fprintf(stderr, "ERROR: CPU #%d not found, only %d CPUs available\n",
			    affinity, max_cpus);
			error = 1;
		}
	}

	if (num_threads < 0 || num_threads > 255)
		error = 1;

	if (priority < 0 || priority > 99)
		error = 1;

	if (num_threads < 1)
		error = 1;

	if (priority && smp)
		sameprio = 1;

	if (timeout < 0)
		error = 1;

	if (error)
		display_help ();
}


static int volatile shutdown;

static void sighand(int sig)
{
	shutdown = 1;
}

int main(int argc, char *argv[])
{
	int i;
	int max_cpus = sysconf(_SC_NPROCESSORS_CONF);
	int oldsamples = 1;
	struct params *receiver = NULL;
	struct params *sender = NULL;
	sigset_t sigset;
	struct timespec maindelay;
	int oflag = O_CREAT|O_RDWR;
	struct mq_attr mqstat;

	memset(&mqstat, 0, sizeof(mqstat));
	mqstat.mq_maxmsg = 1;
	mqstat.mq_msgsize = 8;
	mqstat.mq_flags = 0;

	process_options(argc, argv);

	if (check_privs())
		return 1;

	if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
		perror("mlockall");
		return 1;
	}

	signal(SIGINT, sighand);
	signal(SIGTERM, sighand);

	receiver = calloc(num_threads, sizeof(struct params));
	sender = calloc(num_threads, sizeof(struct params));
	if (receiver == NULL || sender == NULL)
		goto nomem;

	for (i = 0; i < num_threads; i++) {
		char mqname[16];

		sprintf(mqname, SYNCMQ_NAME, i);
		receiver[i].syncmq = mq_open(mqname, oflag, 0777, &mqstat);
		if (receiver[i].syncmq == (mqd_t) -1) {
			fprintf(stderr, "could not open POSIX message queue #1\n");
			return 1;
		}
		sprintf(mqname, TESTMQ_NAME, i);
		receiver[i].testmq = mq_open(mqname, oflag, 0777, &mqstat);
		if (receiver[i].testmq == (mqd_t) -1) {
			fprintf(stderr, "could not open POSIX message queue #2\n");
			return 1;
		}

		receiver[i].mindiff = UINT_MAX;
		receiver[i].maxdiff = 0;
		receiver[i].sumdiff = 0.0;

		receiver[i].num = i;
		receiver[i].cpu = i;
		switch (setaffinity) {
		case AFFINITY_UNSPECIFIED: receiver[i].cpu = -1; break;
		case AFFINITY_SPECIFIED: receiver[i].cpu = affinity; break;
		case AFFINITY_USEALL: receiver[i].cpu = i % max_cpus; break;
		}
		receiver[i].priority = priority;
		receiver[i].tracelimit = tracelimit;
		if (priority > 1 && !sameprio)
			priority--;
		receiver[i].delay.tv_sec = interval / USEC_PER_SEC;
		receiver[i].delay.tv_nsec = (interval % USEC_PER_SEC) * 1000;
		interval += distance;
		receiver[i].max_cycles = max_cycles;
		receiver[i].sender = 0;
		receiver[i].neighbor = &sender[i];
		receiver[i].timeout = timeout;
		pthread_create(&receiver[i].threadid, NULL, pmqthread, &receiver[i]);
		memcpy(&sender[i], &receiver[i], sizeof(receiver[0]));
		sender[i].sender = 1;
		sender[i].neighbor = &receiver[i];
		pthread_create(&sender[i].threadid, NULL, pmqthread, &sender[i]);
	}

	maindelay.tv_sec = 0;
	maindelay.tv_nsec = 50000000; /* 50 ms */

	while (!shutdown) {
		int printed;
		int errorlines = 0;

		for (i = 0; i < num_threads; i++)
			shutdown |= receiver[i].shutdown | sender[i].shutdown;

		if (receiver[0].samples > oldsamples || shutdown) {
			for (i = 0; i < num_threads; i++) {
				printf("#%1d: ID%d, P%d, CPU%d, I%ld; #%1d: ID%d, P%d, CPU%d, Cycles %d\n",
				    i*2, receiver[i].tid, receiver[i].priority, receiver[i].cpu,
				    receiver[i].delay.tv_nsec / 1000,
				    i*2+1, sender[i].tid, sender[i].priority, sender[i].cpu,
				    sender[i].samples);
			}
			for (i = 0; i < num_threads; i++) {
				printf("#%d -> #%d, Min %4d, Cur %4d, Avg %4d, Max %4d\n",
					i*2+1, i*2,
					receiver[i].mindiff, (int) receiver[i].diff.tv_usec,
					(int) ((receiver[i].sumdiff / receiver[i].samples) + 0.5),
					receiver[i].maxdiff);
				if (receiver[i].error[0] != '\0') {
					printf(receiver[i].error);
					errorlines++;
					receiver[i].error[0] = '\0';
				}
				if (sender[i].error[0] != '\0') {
					printf(sender[i].error);
					errorlines++;
					receiver[i].error[0] = '\0';
				}
			}
			printed = 1;
		} else
			printed = 0;

		sigemptyset(&sigset);
		sigaddset(&sigset, SIGTERM);
		sigaddset(&sigset, SIGINT);
		pthread_sigmask(SIG_SETMASK, &sigset, NULL);

		nanosleep(&maindelay, NULL);

		sigemptyset(&sigset);
		pthread_sigmask(SIG_SETMASK, &sigset, NULL);

		if (printed && !shutdown)
			printf("\033[%dA", num_threads*2 + errorlines);
	}

	for (i = 0; i < num_threads; i++) {
		receiver[i].shutdown = 1;
		sender[i].shutdown = 1;
	}
	nanosleep(&receiver[0].delay, NULL);

	for (i = 0; i < num_threads; i++) {
		mq_close(receiver[i].syncmq);
		mq_close(receiver[i].testmq);
		if (!receiver[i].stopped)
			pthread_kill(receiver[i].threadid, SIGTERM);
		if (!sender[i].stopped)
			pthread_kill(sender[i].threadid, SIGTERM);
	}

	nomem:

	return 0;
}


^ 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.