renamed openair-cn to openair3
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7886 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those
|
||||
* of the authors and should not be interpreted as representing official policies,
|
||||
* either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
/*****************************************************************************
|
||||
Source timer.c
|
||||
|
||||
Version 0.1
|
||||
|
||||
Date 2012/11/27
|
||||
|
||||
Product Test
|
||||
|
||||
Subsystem Timer utility main test
|
||||
|
||||
Author Frederic Maurel
|
||||
|
||||
Description Tests the timer utility functions
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#include "nas_timer.h"
|
||||
#include "commonDef.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h> // printf
|
||||
#include <stdlib.h> // exit
|
||||
#include <time.h> // clock_gettime
|
||||
#include <poll.h> // poll
|
||||
|
||||
/****************************************************************************/
|
||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
||||
/****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/******************* L O C A L D E F I N I T I O N S *******************/
|
||||
/****************************************************************************/
|
||||
|
||||
#define TIMER_1S 1 /* 1 second */
|
||||
#define TIMER_2S 2 /* 2 seconds */
|
||||
#define TIMER_3S 3 /* 3 seconds */
|
||||
#define TIMER_4S 4 /* 4 seconds */
|
||||
|
||||
typedef struct {
|
||||
unsigned int id;
|
||||
unsigned int sec;
|
||||
struct timespec start;
|
||||
} _timer_t;
|
||||
|
||||
static void* _timer_callback(void* args);
|
||||
static void* _timer_callback_joinable(void* args);
|
||||
|
||||
static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static unsigned int _nb_timers = 0;
|
||||
static int _start(_timer_t* timer, unsigned int sec);
|
||||
static int _stop(_timer_t* timer);
|
||||
|
||||
/****************************************************************************/
|
||||
/****************** E X P O R T E D F U N C T I O N S ******************/
|
||||
/****************************************************************************/
|
||||
|
||||
int main (int argc, const char* argv[])
|
||||
{
|
||||
int rc;
|
||||
_timer_t timer1, timer2, timer3, timer4;
|
||||
|
||||
#define NB_TIMERS_MAX 10
|
||||
_timer_t timer[NB_TIMERS_MAX];
|
||||
|
||||
/* Initialize timer utility */
|
||||
rc = timer_init();
|
||||
|
||||
if (rc == RETURNerror) {
|
||||
printf("ERROR: timer_init() failed\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Start NB_TIMERS_MAX timers to expire at time interval of 1s */
|
||||
for (int i=0; i < NB_TIMERS_MAX; i++) {
|
||||
if (_start(&timer[i], i) != RETURNok) {
|
||||
printf("ERROR: timer_start(i=%u) failed\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start timer 1 to expire in 1s */
|
||||
if (_start(&timer1, TIMER_1S) != RETURNok) {
|
||||
printf("ERROR: timer_start() failed\n");
|
||||
}
|
||||
|
||||
/* Start timer 2 to expire in 3s */
|
||||
if (_start(&timer2, TIMER_3S) != RETURNok) {
|
||||
printf("ERROR: timer_start() failed\n");
|
||||
}
|
||||
|
||||
/* Start timer 3 to expire in 2s */
|
||||
if (_start(&timer3, TIMER_2S) != RETURNok) {
|
||||
printf("ERROR: timer_start() failed\n");
|
||||
}
|
||||
|
||||
/* Stop timer 1 */
|
||||
if (_stop(&timer1) != RETURNok) {
|
||||
printf("ERROR: timer_stop(id=%u) failed\n", timer3.id);
|
||||
}
|
||||
|
||||
/* Wait for the first timer to expire */
|
||||
poll(0, 0, -1);
|
||||
|
||||
/* Start timer 4 to expire in 4s */
|
||||
if (_start(&timer4, TIMER_4S) != RETURNok) {
|
||||
printf("ERROR: timer_start() failed\n");
|
||||
}
|
||||
|
||||
/* Wait for all timers to expire */
|
||||
while (_nb_timers > 0) {
|
||||
poll(0, 0, 10000);
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/********************* L O C A L F U N C T I O N S *********************/
|
||||
/****************************************************************************/
|
||||
|
||||
static int _timespec_sub(struct timespec* a, struct timespec* b, struct timespec* result)
|
||||
{
|
||||
if (a->tv_sec < b->tv_sec) return -1;
|
||||
else if (a->tv_nsec < b->tv_nsec) return -1;
|
||||
|
||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||
result->tv_nsec = a->tv_nsec - b->tv_nsec;
|
||||
|
||||
if (result->tv_nsec < 0) {
|
||||
result->tv_sec--;
|
||||
result->tv_nsec += 1000000000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* _timer_callback(void* args)
|
||||
{
|
||||
_timer_t* timer = (_timer_t*) args;
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
if (_timespec_sub(&ts, &timer->start, &ts) < 0) {
|
||||
printf("ERROR:_timespec_sub() failed: %ld.%.9ld > %ld.%.9ld\n",
|
||||
timer->start.tv_sec, timer->start.tv_nsec,
|
||||
ts.tv_sec, ts.tv_nsec);
|
||||
} else {
|
||||
printf("%s\t: Timer %u expired after %ld.%.9ld seconds (%u s)\n",
|
||||
__FUNCTION__, timer->id, ts.tv_sec, ts.tv_nsec, timer->sec);
|
||||
timer->id = timer_stop(timer->id);
|
||||
pthread_mutex_lock(&_mutex);
|
||||
_nb_timers -= 1;
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* _timer_callback_joinable(void* args)
|
||||
{
|
||||
_timer_t* timer = (_timer_t*) args;
|
||||
struct timespec ts;
|
||||
int* rc = (int*)malloc(sizeof(int));
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
if (_timespec_sub(&ts, &timer->start, &ts) < 0) {
|
||||
printf("ERROR:_timespec_sub() failed: %ld.%.9ld > %ld.%.9ld\n",
|
||||
timer->start.tv_sec, timer->start.tv_nsec,
|
||||
ts.tv_sec, ts.tv_nsec);
|
||||
*rc = RETURNerror;
|
||||
} else {
|
||||
printf("%s\t: Timer %u expired after %ld.%.9ld seconds (%u s)\n",
|
||||
__FUNCTION__, timer->id, ts.tv_sec, ts.tv_nsec, timer->sec);
|
||||
timer->id = timer_stop(timer->id);
|
||||
pthread_mutex_lock(&_mutex);
|
||||
_nb_timers -= 1;
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
*rc = timer->id;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _start(_timer_t* timer, unsigned int sec)
|
||||
{
|
||||
int rc = RETURNerror;
|
||||
|
||||
timer->sec = sec;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timer->start);
|
||||
timer->id = timer_start(timer->sec, _timer_callback_joinable,
|
||||
(void*) timer);
|
||||
|
||||
if (timer->id != TIMER_INACTIVE_ID) {
|
||||
printf("Timer id=%u scheduled to expire in %u seconds\n",
|
||||
timer->id, timer->sec);
|
||||
_nb_timers += 1;
|
||||
rc = RETURNok;
|
||||
}
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static int _stop(_timer_t* timer)
|
||||
{
|
||||
int rc = RETURNerror;
|
||||
|
||||
printf("Stop timer id=%u\n", timer->id);
|
||||
timer->id = timer_stop(timer->id);
|
||||
|
||||
if (timer->id == TIMER_INACTIVE_ID) {
|
||||
_nb_timers -= 1;
|
||||
rc = RETURNok;
|
||||
}
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user