File indexing completed on 2025-05-11 08:24:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #ifdef HAVE_CONFIG_H
0046 #include "config.h"
0047 #endif
0048
0049 #define CONFIGURE_INIT
0050 #include "system.h"
0051 #include <pthread.h> /* thread facilities */
0052 #include <signal.h> /* signal facilities */
0053 #include <unistd.h> /* sleep facilities */
0054 #include <sched.h> /* schedule facilities */
0055 #include <time.h> /* time facilities */
0056 #include <stdio.h> /* console facilities */
0057 #include <rtems/posix/timerimpl.h>
0058 #include <rtems/score/timespec.h>
0059 #include "pritime.h"
0060
0061 const char rtems_test_name[] = "PSXTIMER 1";
0062
0063 void StopTimer(
0064 timer_t timer_id,
0065 struct itimerspec *timerdata
0066 );
0067
0068
0069
0070 struct periodic_params {
0071 struct timespec period;
0072 int count;
0073 int signo;
0074 int id;
0075 };
0076
0077 pthread_attr_t attr;
0078
0079
0080
0081 struct shared_data {
0082 pthread_mutex_t mutex;
0083 pthread_cond_t sync;
0084 int updated;
0085 };
0086
0087 struct shared_data data;
0088
0089 void StopTimer(
0090 timer_t timer_id,
0091 struct itimerspec *timerdata
0092 )
0093 {
0094 static int firstTime = 1;
0095 struct itimerspec *pOld;
0096 struct itimerspec odata;
0097
0098
0099
0100
0101
0102 pOld = (firstTime == 1) ? NULL : &odata;
0103 firstTime = 0;
0104
0105 timerdata->it_value.tv_sec = 0;
0106 timerdata->it_value.tv_nsec = 0;
0107 if (timer_settime(timer_id,POSIX_TIMER_RELATIVE,timerdata,pOld) == -1) {
0108 perror ("Error in timer setting\n");
0109 rtems_test_exit(0);
0110 }
0111 }
0112
0113
0114 void * task_a (void *arg)
0115 {
0116 struct timespec my_period;
0117 int my_sig, received_sig;
0118 struct itimerspec timerdata;
0119 struct itimerspec timergetdata;
0120 timer_t timer_id;
0121 time_t clock;
0122 struct sigevent event;
0123 sigset_t set;
0124 struct periodic_params *params;
0125
0126 params = arg;
0127 my_period = params->period;
0128 my_sig = params->signo;
0129
0130
0131 event.sigev_notify = SIGEV_SIGNAL;
0132 event.sigev_signo = my_sig;
0133 if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1) {
0134 perror ("Error in timer creation\n");
0135 rtems_test_exit(0);
0136 }
0137
0138
0139 sigemptyset (&set);
0140 sigaddset (&set,my_sig);
0141 pthread_sigmask(SIG_BLOCK,&set,NULL);
0142
0143
0144 timerdata.it_interval = my_period;
0145 timerdata.it_value = my_period;
0146 timerdata.it_value.tv_sec *= 2;
0147 if (timer_settime(timer_id,POSIX_TIMER_RELATIVE,&timerdata,&timergetdata) == -1) {
0148 perror ("Error in timer setting\n");
0149 rtems_test_exit(0);
0150 }
0151 printf(
0152 "task A: timer_settime - value=%" PRIdtime_t ":%ld interval=%" PRIdtime_t ":%ld\n",
0153 timergetdata.it_value.tv_sec, timergetdata.it_value.tv_nsec,
0154 timergetdata.it_interval.tv_sec, timergetdata.it_interval.tv_nsec
0155 );
0156
0157
0158
0159 while(1) {
0160 if (sigwait(&set,&received_sig) == -1) {
0161 perror ("Error in sigwait\n");
0162 }
0163 if (timer_gettime(timer_id, &timerdata) == -1) {
0164 perror ("Error in timer_gettime\n");
0165 rtems_test_exit(0);
0166 }
0167 if (! _Timespec_Equal_to( &timerdata.it_value, &my_period )){
0168 fprintf(
0169 stderr, "Error in Task A timer_gettime:\n"
0170 " re-armed timer: %" PRIdtime_t ":%ld does not match interval: %" PRIdtime_t ":%ld\n",
0171 timerdata.it_value.tv_sec, timerdata.it_value.tv_nsec,
0172 my_period.tv_sec, my_period.tv_nsec
0173 );
0174 }
0175 clock = time(NULL);
0176 printf("Executing task A with count = %2i %s", params->count, ctime(&clock));
0177 params->count--;
0178 if (params->count == 0)
0179 StopTimer(timer_id, &timerdata);
0180 }
0181 return NULL;
0182 }
0183
0184
0185
0186 void * task_b (void *arg)
0187 {
0188 struct timespec my_period;
0189 struct timespec now;
0190 int my_sig, received_sig;
0191 struct itimerspec timerdata;
0192 timer_t timer_id;
0193 time_t clock;
0194 struct sigevent event;
0195 sigset_t set;
0196 struct periodic_params *params;
0197
0198 params = arg;
0199 my_period = params->period;
0200 my_sig = params->signo;
0201
0202
0203
0204 event.sigev_notify = SIGEV_SIGNAL;
0205 event.sigev_signo = my_sig;
0206 if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1) {
0207 perror ("Error in timer creation\n");
0208 rtems_test_exit(0);
0209 }
0210
0211
0212 sigemptyset (&set);
0213 sigaddset (&set,my_sig);
0214 pthread_sigmask(SIG_BLOCK,&set,NULL);
0215
0216
0217 clock_gettime( CLOCK_REALTIME, &now );
0218 timerdata.it_interval = my_period;
0219 timerdata.it_value = now;
0220 _Timespec_Add_to( &timerdata.it_value, &my_period );
0221 if (timer_settime(timer_id,TIMER_ABSTIME,&timerdata,NULL) == -1) {
0222 perror ("Error in timer setting\n");
0223 rtems_test_exit(0);
0224 }
0225
0226
0227 while(1) {
0228 if (sigwait(&set,&received_sig) == -1) {
0229 perror ("Error in sigwait\n");
0230 rtems_test_exit(0);
0231 }
0232
0233 if (timer_gettime(timer_id, &timerdata) == -1) {
0234 perror ("Error in timer_gettime\n");
0235 rtems_test_exit(0);
0236 }
0237
0238 #if 0
0239
0240
0241
0242
0243 if ( !_Timespec_Equal_to( &timerdata.it_value, &my_period) ){
0244 printf( "NOT EQUAL %d:%d != %d:%d\n",
0245 timerdata.it_value.tv_sec,
0246 timerdata.it_value.tv_nsec,
0247 my_period.tv_sec,
0248 my_period.tv_nsec
0249 );
0250 rtems_test_exit(0);
0251 }
0252 #endif
0253
0254 pthread_mutex_lock (&data.mutex);
0255 clock = time(NULL);
0256 printf("Executing task B with count = %2i %s",
0257 params->count, ctime(&clock)
0258 );
0259 data.updated = TRUE;
0260 pthread_cond_signal (&data.sync);
0261 pthread_mutex_unlock (&data.mutex);
0262 params->count--;
0263 if (params->count == 0)
0264 StopTimer(timer_id, &timerdata);
0265 }
0266 return NULL;
0267 }
0268
0269
0270
0271 void * task_c (void *arg)
0272 {
0273 int count;
0274 struct timespec my_period;
0275 int my_sig, received_sig;
0276 struct itimerspec timerdata;
0277 struct itimerspec timergetdata;
0278 timer_t timer_id;
0279 time_t clock;
0280 struct sigevent event;
0281 sigset_t set;
0282 struct periodic_params *params;
0283
0284 params = arg;
0285 my_period = params->period;
0286 my_sig = params->signo;
0287
0288
0289 event.sigev_notify = SIGEV_SIGNAL;
0290 event.sigev_signo = my_sig;
0291 if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1) {
0292 perror ("Error in timer creation\n");
0293 rtems_test_exit(0);
0294 }
0295
0296
0297 sigemptyset (&set);
0298 sigaddset (&set,my_sig);
0299 pthread_sigmask(SIG_BLOCK,&set,NULL);
0300
0301
0302 timerdata.it_interval = my_period;
0303 timerdata.it_value = my_period;
0304 timerdata.it_value.tv_sec *= 2;
0305 if (timer_settime(timer_id,POSIX_TIMER_RELATIVE,&timerdata,NULL) == -1) {
0306 perror ("Error in timer setting\n");
0307 rtems_test_exit(0);
0308 }
0309
0310
0311 for (count=0 ; ; count++) {
0312 if (sigwait(&set,&received_sig) == -1) {
0313 perror ("Error in sigwait\n");
0314 rtems_test_exit(0);
0315 }
0316 if (timer_gettime(timer_id, &timerdata) == -1) {
0317 perror ("Error in timer_gettime\n");
0318 rtems_test_exit(0);
0319 }
0320 if (! _Timespec_Equal_to( &timerdata.it_value, &my_period) ){
0321 fprintf(
0322 stderr, "Error in Task A timer_gettime:\n"
0323 " re-armed timer: %" PRIdtime_t ":%ld does not match interval: %" PRIdtime_t ":%ld\n",
0324 timerdata.it_value.tv_sec, timerdata.it_value.tv_nsec,
0325 my_period.tv_sec, my_period.tv_nsec
0326 );
0327 }
0328 pthread_mutex_lock (&data.mutex);
0329 while (data.updated == FALSE) {
0330 pthread_cond_wait (&data.sync,&data.mutex);
0331 }
0332 clock = time(NULL);
0333 printf("Executing task C with count = %2i %s",
0334 params->count, ctime(&clock)
0335 );
0336
0337 if ( count && (count % 5) == 0 ) {
0338 int overruns = 0;
0339 sleep(1);
0340 overruns = timer_getoverrun( timer_id );
0341 printf( "task C: timer_getoverrun - overruns=%d\n", overruns );
0342
0343 if (timer_gettime(timer_id, &timergetdata) == -1) {
0344 perror ("Error in timer setting\n");
0345 rtems_test_exit(0);
0346 }
0347 printf(
0348 "task C: timer_gettime - %" PRIdtime_t ":%ld remaining from %" PRIdtime_t ":%ld\n",
0349 timergetdata.it_value.tv_sec, timergetdata.it_value.tv_nsec,
0350 timergetdata.it_interval.tv_sec, timergetdata.it_interval.tv_nsec
0351 );
0352 }
0353
0354 pthread_mutex_unlock (&data.mutex);
0355 params->count--;
0356 if (params->count == 0)
0357 StopTimer(timer_id, &timerdata);
0358 }
0359 return NULL;
0360 }
0361
0362
0363
0364 void *POSIX_Init (
0365 void *argument
0366 )
0367
0368 {
0369 pthread_mutexattr_t mutexattr;
0370 pthread_condattr_t condattr;
0371 pthread_attr_t attr;
0372 pthread_t ta,tb,tc, tc1;
0373 sigset_t set;
0374
0375 struct sched_param sch_param;
0376 struct periodic_params params_a, params_b, params_c, params_c1;
0377
0378 TEST_BEGIN();
0379
0380 data.updated = FALSE;
0381
0382
0383 sigemptyset (&set);
0384 sigaddset (&set,SIGALRM);
0385 pthread_sigmask (SIG_BLOCK,&set,NULL);
0386
0387
0388 if (pthread_mutexattr_init (&mutexattr) != 0) {
0389 perror ("Error in mutex attribute init\n");
0390 }
0391
0392
0393 if (pthread_mutex_init (&data.mutex,&mutexattr) != 0) {
0394 perror ("Error in mutex init");
0395 }
0396
0397
0398 if (pthread_condattr_init (&condattr) != 0) {
0399 perror ("Error in condition attribute init\n");
0400 }
0401
0402
0403 if (pthread_cond_init (&data.sync,&condattr) != 0) {
0404 perror ("Error in condition init");
0405 }
0406
0407
0408 if (pthread_attr_init(&attr) != 0) {
0409 perror ("Error in attribute init\n");
0410 }
0411
0412
0413 if (pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED) != 0) {
0414 perror("Error in attribute inheritsched\n");
0415 }
0416
0417
0418 if (pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) != 0) {
0419 perror ("Error in attribute detachstate\n");
0420 }
0421
0422
0423
0424 if (pthread_attr_setschedpolicy (&attr, SCHED_FIFO) != 0) {
0425 perror ("Error in attribute setschedpolicy\n");
0426 }
0427
0428
0429
0430 sch_param.sched_priority = 1;
0431 if (pthread_attr_setschedparam(&attr, &sch_param) != 0) {
0432 perror ("Error in attribute schedparam\n");
0433 }
0434
0435
0436
0437 params_a.period.tv_sec = 1;
0438 params_a.period.tv_nsec = 000000000;
0439 params_a.count = 20;
0440 params_a.signo = SIGALRM;
0441 if (pthread_create (&ta, &attr, task_a, ¶ms_a) != 0 ) {
0442 perror ("Error in thread create for task a\n");
0443 }
0444
0445
0446
0447 sch_param.sched_priority = 15;
0448 if (pthread_attr_setschedparam(&attr, &sch_param) != 0) {
0449 perror ("Error in attribute schedparam");
0450 }
0451
0452
0453 params_b.period.tv_sec = 2;
0454 params_b.period.tv_nsec = 000000000;
0455 params_b.count = 10;
0456 params_b.signo = SIGALRM;
0457 if (pthread_create (&tb, &attr, task_b, ¶ms_b) != 0) {
0458 perror ("Error in thread create for task b\n");
0459 }
0460
0461
0462
0463 sch_param.sched_priority = 14;
0464 if (pthread_attr_setschedparam(&attr, &sch_param) != 0 ) {
0465 perror ("Error in attribute schedparam\n");
0466 }
0467
0468
0469 params_c.period.tv_sec = 3;
0470 params_c.period.tv_nsec = 000000000;
0471 params_c.count = 6;
0472 params_c.signo = SIGALRM;
0473 if (pthread_create (&tc, &attr, task_c, ¶ms_c) != 0) {
0474 perror ("Error in thread create for task c\n");
0475 }
0476
0477
0478 sleep (25);
0479
0480 puts( "starting C again with 0.5 second periodicity" );
0481
0482 params_c1.period.tv_sec = 0;
0483 params_c1.period.tv_nsec = 500000000;
0484 params_c1.count = 6;
0485 params_c1.signo = SIGALRM;
0486 if (pthread_create (&tc1, &attr, task_c, ¶ms_c1) != 0) {
0487 perror ("Error in thread create for task c1\n");
0488 }
0489
0490 sleep(5);
0491
0492 TEST_END();
0493 rtems_test_exit (0);
0494 }