//POSIX.1b Timer
|
#include <jni.h>
|
#include <stdbool.h>
|
#include <stdint.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <unistd.h>
|
#include <signal.h>
|
#include <string.h>
|
#include <sys/time.h>
|
#include <pthread.h>
|
#include <errno.h>
|
#include <time.h>
|
#include "../jni_log.h"
|
#include "apptimer.h"
|
|
#define MAX_TIMER 32
|
|
static struct {
|
timer_t timerId;
|
|
void (*func)(union sigval sig);
|
|
int value;
|
uint8_t *user_data;
|
} AppTimer[MAX_TIMER];
|
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static int createTimer(timer_t *timerId, void (*func)(union sigval sig),
|
int value,
|
uint8_t *usr_data, int usr_data_length,
|
uint8_t **usr_data_ptr) {
|
struct sigevent sev;
|
pthread_attr_t attr;
|
|
// Register printMsg to SIGALRM
|
pthread_attr_init(&attr);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
|
|
memset(&sev, 0, sizeof(sev));
|
|
sev.sigev_notify = SIGEV_THREAD;
|
sev.sigev_notify_function = func;
|
sev.sigev_notify_attributes = &attr;
|
|
if (usr_data != NULL && usr_data_length != 0) {
|
if ((sev.sigev_value.sival_ptr = malloc(usr_data_length)) != NULL) {
|
*usr_data_ptr = (uint8_t *) sev.sigev_value.sival_ptr;
|
memcpy(sev.sigev_value.sival_ptr, usr_data, usr_data_length); //Copy usr data
|
sev.sigev_value.sival_int = usr_data_length;
|
} else {
|
return -1;
|
}
|
} else {
|
sev.sigev_value.sival_int = value;
|
}
|
|
/* create timer */
|
if (timer_create(CLOCK_REALTIME, &sev, timerId) == -1) {
|
return -1;
|
}
|
// LOGD("timer_create\n");
|
return 0;
|
}
|
|
static int setTimer(timer_t timerId, int timeMSec) {
|
struct itimerspec its;
|
|
/* Start the timer */
|
its.it_value.tv_sec = timeMSec / 1000;
|
its.it_value.tv_nsec = (timeMSec % 1000) * 1000000;
|
|
its.it_interval.tv_sec = 0;
|
its.it_interval.tv_nsec = 0;
|
|
if (timer_settime(timerId, 0, &its, NULL) == -1) {
|
return -1;
|
}
|
// LOGD("timer_settime\n");
|
return 0;
|
}
|
|
void AppTimer_Init(void) {
|
memset(AppTimer, 0, sizeof(AppTimer));
|
pthread_mutex_init(&mutex, NULL);
|
}
|
|
void AppTimer_add(void (*func)(union sigval), int timeMS) {
|
int i;
|
// LOGD("AppTimer_add\n");
|
pthread_mutex_lock(&mutex);
|
for (i = 0; i < MAX_TIMER; i++) {
|
if (AppTimer[i].func == NULL) {
|
if (createTimer(&(AppTimer[i].timerId), func, 0, NULL, 0, &(AppTimer[i].user_data)) == 0) {
|
AppTimer[i].func = func;
|
|
if (setTimer(AppTimer[i].timerId, timeMS) !=
|
0) { //Set timer fail, delele it
|
timer_delete(AppTimer[i].timerId);
|
if (AppTimer[i].user_data != NULL) {
|
free(AppTimer[i].user_data);
|
AppTimer[i].user_data = NULL;
|
}
|
AppTimer[i].func = NULL;
|
}
|
}
|
break;
|
}
|
}
|
pthread_mutex_unlock(&mutex);
|
}
|
|
void AppTimer_add(void (*func)(union sigval), int timeMS, uint8_t *data, int length) {
|
int i;
|
// LOGD("AppTimer_add\n");
|
pthread_mutex_lock(&mutex);
|
for (i = 0; i < MAX_TIMER; i++) {
|
if (AppTimer[i].func == NULL) {
|
if (createTimer(&(AppTimer[i].timerId), func, 0, data, length, &(AppTimer[i].user_data)) == 0) {
|
AppTimer[i].func = func;
|
|
if (setTimer(AppTimer[i].timerId, timeMS) !=
|
0) { //Set timer fail, delele it
|
timer_delete(AppTimer[i].timerId);
|
if (AppTimer[i].user_data != NULL) {
|
free(AppTimer[i].user_data);
|
AppTimer[i].user_data = NULL;
|
}
|
AppTimer[i].func = NULL;
|
}
|
}
|
break;
|
}
|
}
|
pthread_mutex_unlock(&mutex);
|
}
|
|
void AppTimer_add(void (*func)(union sigval), int timeMS, int value) {
|
int i;
|
// LOGD("AppTimer_add\n");
|
pthread_mutex_lock(&mutex);
|
for (i = 0; i < MAX_TIMER; i++) {
|
if (AppTimer[i].func == NULL) {
|
if (createTimer(&(AppTimer[i].timerId), func, value, NULL, 0, &(AppTimer[i].user_data)) == 0) {
|
AppTimer[i].func = func;
|
|
if (setTimer(AppTimer[i].timerId, timeMS) !=
|
0) { //Set timer fail, delele it
|
timer_delete(AppTimer[i].timerId);
|
if (AppTimer[i].user_data != NULL) {
|
free(AppTimer[i].user_data);
|
AppTimer[i].user_data = NULL;
|
}
|
AppTimer[i].func = NULL;
|
}
|
}
|
break;
|
}
|
}
|
pthread_mutex_unlock(&mutex);
|
}
|
|
void AppTimer_delete(void (*func)(union sigval)) {
|
int i;
|
// LOGD("AppTimer_delete\n");
|
pthread_mutex_lock(&mutex);
|
for (i = 0; i < MAX_TIMER; i++) {
|
if (AppTimer[i].func == func) {
|
timer_delete(AppTimer[i].timerId);
|
if (AppTimer[i].user_data != NULL) {
|
free(AppTimer[i].user_data);
|
AppTimer[i].user_data = NULL;
|
}
|
AppTimer[i].func = NULL;
|
}
|
}
|
pthread_mutex_unlock(&mutex);
|
}
|
|
uint32_t AppTimer_GetTickCount(void)
|
{
|
struct timespec ts;
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
|
}
|