/*************************************************************************
> File Name: rt-test.c
> Author:
> Mail:
> Created Time: 2019年04月10日 09时09分15秒 CST
************************************************************************/
#define _GNU_SOURCE
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
#include <signal.h>
#define SCHED_PRIORITY 80
#define SCHED_POLICY SCHED_RR //SCHED_FIFO
#define BIND_CPU 0
#define NSEC_PER_SEC 1000000000
#define USEC_PER_SEC 1000000
#define MSEC_PER_SEC 1000
#define RT_DELAY_MS (1*(NSEC_PER_SEC/MSEC_PER_SEC))
#define RT_DELAY_TIME RT_DELAY_MS
static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER;
static unsigned long max_delay = 0; static unsigned long max_operation = 0;
static unsigned long cur_delay = 0; static unsigned long cur_operation = 0;
static unsigned long ave_delay = 0; static unsigned long ave_operation = 0; //volatile double *a; volatile double *b;
unsigned long cyctimes = 0; unsigned long cyc_count = 0;
static int setscheduler(pid_t pid, int policy, const struct sched_param *param)
{
int err = 0;
err = sched_setscheduler(pid, policy, param);
if(err != 0)
{
perror("setscheduler");
}
return err;
}
int set_cpu(int cpuno)
{
int max_cpus = sysconf(_SC_NPROCESSORS_ONLN);
pthread_t tid;
cpu_set_t mask;
if(cpuno >=0 && cpuno < max_cpus)
{
CPU_ZERO(&mask);
CPU_SET(cpuno, &mask);
tid = pthread_self();
if(pthread_setaffinity_np(tid, sizeof(mask), &mask) == -1)
{
printf("Could not set CPU affinity to CPU #%d\n", cpuno);
return -1;
}
return 0;
}
return -1;
}
void tsnorm(struct timespec *ts)
{
while (ts->tv_nsec >= NSEC_PER_SEC)
{
ts->tv_nsec -= NSEC_PER_SEC;
ts->tv_sec++;
}
}
static inline unsigned long long calcdiff(struct timespec t1, struct timespec t2)
{
unsigned long long diff;
diff = USEC_PER_SEC * (long long)((int) t1.tv_sec - (int) t2.tv_sec);
diff += ((int) t1.tv_nsec - (int) t2.tv_nsec) / 1000;
return diff; } static inline int tsgreater(struct timespec *a, struct timespec *b) {
return ((a->tv_sec > b->tv_sec) || (a->tv_sec == b->tv_sec && a->tv_nsec > b->tv_nsec)); } void *rtthread(void *s) {
struct sched_param schedp;
struct timespec now,now1,next,interval;
int ret,i;
unsigned long long diff;
long times;
unsigned long tmp;
unsigned long sum_delay = 0,sum_operation = 0;
cyc_count = 0;
srand(time(×));
set_cpu(BIND_CPU);
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = SCHED_PRIORITY;
if (setscheduler(0, SCHED_POLICY, &schedp))
{
printf("timerthread%d: failed to set priority to %d\n", BIND_CPU, SCHED_PRIORITY);
}
interval.tv_sec = RT_DELAY_TIME/NSEC_PER_SEC;
interval.tv_nsec = RT_DELAY_TIME % NSEC_PER_SEC;
clock_gettime(CLOCK_REALTIME,&now);
next = now;
next.tv_sec += interval.tv_sec;
next.tv_nsec += interval.tv_nsec;
tsnorm(&next);
while(1)
{
ret = clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&next,NULL);
if(ret != 0)
{
perror("clock_nanosleep");
exit(-1);
}
clock_gettime(CLOCK_REALTIME,&now);
diff = calcdiff(now,next);
cur_delay = diff;
if(diff > max_delay)
{
max_delay = diff;
//pthread_cond_signal(&refresh_on_max_cond);
}
/**************operation*******************/
#if 0
for(i = 0;i < cyctimes;i++)
{
a[i] = sin((double)(rand()%50)+3.14);
b[i] = cos((double)(rand()%50)+10.14);
a[0] += a[i] + b[i];
}
#endif
/*****************************************/
clock_gettime(CLOCK_REALTIME,&now1);
diff = calcdiff(now1,now);
cur_operation = diff;
if(diff > max_operation)
{
max_operation = diff;
//pthread_cond_signal(&refresh_on_max_cond);
}
sum_delay += cur_delay;
sum_operation += cur_operation;
cyc_count++;
ave_delay = sum_delay / cyc_count;
ave_operation = sum_operation / cyc_count;
pthread_cond_signal(&refresh_on_max_cond);
next.tv_sec += interval.tv_sec;
next.tv_nsec += interval.tv_nsec;
tsnorm(&next);
while (tsgreater(&now1, &next))
{
next.tv_sec += interval.tv_sec;
next.tv_nsec += interval.tv_nsec;
tsnorm(&next);
}
}
return NULL;
}
void print_stat(void)
{
printf("cyc,%7ld,\tcur shake time,%5ld,\tave shake time,%5ld,\tmax shake time,%5ld\n",cyc_count,cur_delay,ave_delay,max_delay);
printf("cyc,%7ld,\tcur operation time,%5ld,\tave operation time,%5ld,\tmax operation time,%5ld\n",cyc_count,cur_operation,ave_operation,max_operation);
printf("\033[3A");
}
void stat_clean(void)
{
cur_delay = 0;
cur_operation = 0;
max_delay = 0;
max_operation = 0;
}
void *print_thread(void *s)
{
while(1)
{
print_stat();
pthread_mutex_lock(&refresh_on_max_lock);
pthread_cond_wait(&refresh_on_max_cond,&refresh_on_max_lock);
pthread_mutex_unlock(&refresh_on_max_lock);
}
return NULL;
}
pthread_t tid[2];
void alarm_killpthread(int no)
{
pthread_cancel(tid[0]);
}
int main(int argc,char **argv)
{
int count = 0;
int ret = 0;
if(argc == 1)
{
cyctimes = 50;
}
else if(argc == 2)
{
cyctimes = atoi(argv[1]);
if(cyctimes == 0)
{
printf("example : ./a.out cyctimes\n");
return -1;
}
}
else
{
printf("example : ./a.out cyctimes\n");
return -1;
}
pthread_create(&tid[1],NULL,print_thread,NULL);
signal(SIGALRM,alarm_killpthread);
while(count < 100)
{
sleep(10);
ret = pthread_create(&tid[0],NULL,rtthread,NULL);
if(ret != 0)
{
perror("pthread_create");
return -1;
}
alarm(120);
pthread_join(tid[0],NULL);
printf("\033[3B");
printf("thread %d been kill !!!\n",count);
stat_clean();
count++;
}
return 0;
}
linux测试系统实时性代码(当前\平均\最大抖动和操作时长)
最新推荐文章于 2025-07-13 19:05:58 发布