several large jitters during long time running of two periodic tasks

YamatoKira <[email protected]> Mon, 26 Sep 2016 09:23:09 +0800
Newsgroups gmane.linux.real-time.rtai
Message-ID <[email protected]>
Hello, everyone
I run a program with two periodic tasks in two threads in userspace on LinuxCNC for 3000 seconds, and found that several large jitters of the period: the two periods I chose are 500μs--1ms  and 1ms--2ms, and the jitters almost reached 1000ms..... I run the program on two machines, and the similar result happened.
Is this phenomena result from that the codes run in userspace? Or is it due to the file operation to record the results which break the realtime behavior? 
I attatched my codes and the plot of results hope that will help for analysis......
3Q for your patience to read this end
                                                                                       yours: C.P.                                                                                      2016-09-26

_______________________________________________
Rtai mailing list
[email protected]
https://mail.rtai.org/cgi-bin/mailman/listinfo/rtai
period1.jpg (image/jpeg, 51.7 KB) - not displayed
period1.jpg (image/jpeg, 36.9 KB) - not displayed
period2.jpg (image/jpeg, 36.5 KB) - not displayed
functions.c (text/plain, 3.4 KB)
//functions.c
#include"globals.h"

void *main_loop_1(void * args)
{
	//RTIME sampling_interval = (RTIME *)args;
	RTIME sampling_interval_1 = nano2count(LOOP_1_PERIOD_NS);
	//printf("loop 1 sampling_interval_1= %lld\n",sampling_interval_1);
	//getchar();
	static RTIME expected;
	int i = 0;
	unsigned char temp, data;
	RTIME loop_1_time;
	RTIME loop_1_old_time;
	RTIME loop_1_period;
	RTIME loop_1_jitter;

	FILE * fid_1=fopen("ThreadRecord1.txt","w");
	if(NULL==fid_1)
	{
		printf("Open 1 Error");
	}

	usleep(10);

	if (!(loop_Task_1 = rt_task_init_schmod(nam2num("RTAI01"),
		2,
		0,
		0,
		SCHED_FIFO,
		0x3)))
	{
		printf("ERROR: Can not initialize thread task\n");
		exit(1);
	}
	expected = rt_get_time() + sampling_interval_1;

	//printf("loop 1 sampling_interval_1= %lld\n",sampling_interval_1);

	rt_task_make_periodic(loop_Task_1, expected, sampling_interval_1);
	
	rt_make_hard_real_time();

	loop_1_old_time = rt_get_time_ns();
	//printf("LOOP_1 Time %lld\n",loop_1_old_time);

	usleep(10);
	while (keep_on_running)
	{
		i++;
		loop_1_time=rt_get_time_ns();
		loop_1_period=loop_1_time-loop_1_old_time;
		loop_1_jitter=loop_1_period-LOOP_1_PERIOD_NS;

		// printf("LOOP_1\t%d\tTime\t%lld\tPeriod\t%lld\tJitter\t%lld\n",
		// 	i,loop_1_time, loop_1_period, loop_1_jitter);
		fprintf(fid_1,"%d\t%lld\t%lld\t%lld\n",
			i,loop_1_time, loop_1_period, loop_1_jitter);
		loop_1_old_time = loop_1_time;
		rt_busy_sleep(0.1*LOOP_1_PERIOD_NS);
		if (i == LOOP_LIMIT_1)
		{
			keep_on_running = 0;
			//printf("LOOP_1 %d run: %d %lld \n",i,keep_on_running, loop_1_time);
			break;
		}
		//getchar();
		rt_task_wait_period();
	}
	rt_task_delete(loop_Task_1);
	fclose(fid_1);
	return 0;
}

void *main_loop_2(void * args)
{
	//RTIME sampling_interval = (RTIME *)args;
	RTIME sampling_interval_2 = nano2count(LOOP_2_PERIOD_NS);
	//printf("loop 2 sampling_interval_2= %lld\n",sampling_interval_2);
	//getchar();
	static RTIME expected;
	int i = 0;
	unsigned char temp, data;
	RTIME loop_2_time;
	RTIME loop_2_old_time;
	RTIME loop_2_period;
	RTIME loop_2_jitter;

	FILE * fid_2=fopen("ThreadRecord2.txt","w");
	if(NULL==fid_2)
	{
		printf("Open 2 Error");
	}

	usleep(10);

	if (!(loop_Task_2 = rt_task_init_schmod(nam2num("RTAI02"),
		2,
		0,
		0,
		SCHED_FIFO,
		0x3)))
	{
		printf("ERROR: Can not initialize thread task\n");
		exit(1);
	}
	expected = rt_get_time() + sampling_interval_2;

	//printf("loop 2 sampling_interval_2= %lld\n",sampling_interval_2);

	rt_task_make_periodic(loop_Task_2, expected, sampling_interval_2);
	
	rt_make_hard_real_time();

	loop_2_old_time = rt_get_time_ns();
	//printf("LOOP_2 Time %lld\n",loop_2_old_time);
	usleep(10);

	while (keep_on_running)
	{
		i++;
		loop_2_time=rt_get_time_ns();
		loop_2_period=loop_2_time-loop_2_old_time;
	    loop_2_jitter=loop_2_period-LOOP_2_PERIOD_NS;
		// printf("LOOP_2\t%d\tTime\t%lld\tPeriod\t%lld\tJitter\t%lld\n",
		// 	i,loop_2_time, loop_2_period, loop_2_jitter);
		fprintf(fid_2,"%d\t%lld\t%lld\t%lld\n",
			i,loop_2_time, loop_2_period, loop_2_jitter);
		loop_2_old_time = loop_2_time;
		rt_busy_sleep(0.1*LOOP_2_PERIOD_NS);
		if (i == LOOP_LIMIT_2)
		{
			keep_on_running = 0;
			// printf("LOOP_2 %d run: %d %lld \n",
			// 	i,keep_on_running, loop_2_time);
			break;
		}
		//getchar();
		rt_task_wait_period();
	}
	rt_task_delete(loop_Task_2);
	fclose(fid_2);
	return 0;
}
rt_skelet.c (text/plain, 1.5 KB)
//rt_skelet.c
#include"globals.h"

int main(int argc, char *argv[])
{
	int    hard_timer_running = 1;
	static RTIME sampling_interval;
	static RTIME main_watch;
	static RTIME last_main_watch;

	keep_on_running = 1;

	if (hard_timer_running == rt_is_hard_timer_running())
	{
		//printf("Skip Hard Real Time Setting\n");
		sampling_interval = nano2count(TICK_TIME);
		//printf("sampling_interval= %lld\n",sampling_interval);
	}
	else
	{
		//printf("Start Real Time Timer...\n");
		rt_set_oneshot_mode();
		start_rt_timer(0);
		sampling_interval = nano2count(TICK_TIME);
		//printf("sampling_interval= %lld\n",sampling_interval);
	}

	//getchar();
	
	//printf("Before rt_task_init_schmod\n");

	if (!(my_task = rt_task_init_schmod(nam2num("MAINTASK"),
		2,
		0,
		0,
		SCHED_FIFO,
		0x3)))
	{
		printf("ERROR: Can not initialize main task\n");
		exit(1);
	}

	//printf("Before pthread_create\n");
	pthread_create(&main_thread_1, NULL, main_loop_1, (void *)sampling_interval);
	pthread_create(&main_thread_2, NULL, main_loop_2, (void *)sampling_interval);
	usleep(10);
	//printf("Before while\n");
	last_main_watch=rt_get_time_ns();
	while (keep_on_running)
	{
		//printf("while keep_on_running\n");
		main_watch=rt_get_time_ns();
		//printf("main_watch %lld %lld\n",main_watch,main_watch-last_main_watch);
		last_main_watch=main_watch;
		//getchar(); 
		usleep(10);
	}
	rt_task_delete(my_task);
	//printf("Program %s will be finished\n", argv[0]);
	return 0;
}
globals.h (text/plain, 571 B)
//////////globals.h//////////

#include<rtai_lxrt.h>
#include<pthread.h>
#include<stdio.h>
#include<unistd.h>

int keep_on_running;

#define TICK_TIME        1000000000
#define LOOP_LIMIT_1     6000
#define LOOP_LIMIT_2     3000
#define LOOP_1_PERIOD_NS  500000        //500 us
#define LOOP_2_PERIOD_NS 1000000        //1   ms

static RT_TASK *my_task;

static pthread_t main_thread_1;

void *main_loop_1(void *args);

static RT_TASK *loop_Task_1;

static pthread_t main_thread_2;

void *main_loop_2(void *args);

static RT_TASK *loop_Task_2;