Release candidate
This commit is contained in:
parent
47ebc07264
commit
bf96e32fe6
52
Makefile
Normal file
52
Makefile
Normal file
@ -0,0 +1,52 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# ******************************************************************************
|
||||
#
|
||||
# @file Makefile
|
||||
#
|
||||
# @brief Makefile for Time Utility Functions library
|
||||
#
|
||||
# @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
#
|
||||
# @date Mar 2024
|
||||
# @author Barrett Edwards <code@jrlabs.io>
|
||||
#
|
||||
# ******************************************************************************
|
||||
|
||||
CC=gcc
|
||||
CFLAGS= -g3 -O0 -Wall -Wextra
|
||||
MACROS=
|
||||
INCLUDE_DIR=/usr/local/include
|
||||
LIB_DIR=/usr/local/lib
|
||||
INCLUDE_PATH=-I $(INCLUDE_DIR)
|
||||
LIB_PATH=-L $(LIB_DIR)
|
||||
LIBS=
|
||||
TARGET=timeutils
|
||||
|
||||
all: testbench lib$(TARGET).a
|
||||
|
||||
testbench: testbench.c main.o
|
||||
$(CC) $^ $(CFLAGS) $(MACROS) $(INCLUDE_PATH) $(LIB_PATH) $(LIBS) -o $@
|
||||
|
||||
lib$(TARGET).a: main.o
|
||||
ar rcs $@ $^
|
||||
|
||||
main.o: main.c main.h
|
||||
$(CC) -c $< $(CFLAGS) $(MACROS) $(INCLUDE_PATH) -o $@
|
||||
|
||||
clean:
|
||||
rm -rf ./*.o ./*.a testbench
|
||||
|
||||
doc:
|
||||
doxygen
|
||||
|
||||
install: lib$(TARGET).a
|
||||
sudo cp lib$(TARGET).a $(LIB_DIR)/
|
||||
sudo cp main.h $(INCLUDE_DIR)/$(TARGET).h
|
||||
|
||||
.PHONY: all clean doc install
|
||||
|
||||
# Variables
|
||||
# $^ Will expand to be all the sensitivity list
|
||||
# $< Will expand to be the frist file in sensitivity list
|
||||
# $@ Will expand to be the target name (the left side of the ":" )
|
||||
# -c gcc will compile but not try and link
|
||||
216
main.c
Normal file
216
main.c
Normal file
@ -0,0 +1,216 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/**
|
||||
* @file timeutils.c
|
||||
*
|
||||
* @brief Code file for Time Utils library
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
*
|
||||
* @date Mar 2024
|
||||
* @author Barrett Edwards <code@jrlabs.io>
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDES ==================================================================*/
|
||||
|
||||
/* printf()
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
/* timespec
|
||||
*/
|
||||
#include <time.h>
|
||||
|
||||
#include "timeutils.h"
|
||||
|
||||
/* MACROS ====================================================================*/
|
||||
|
||||
/* ENUMERATIONS ==============================================================*/
|
||||
|
||||
/* STRUCTS ===================================================================*/
|
||||
|
||||
/* GLOBAL VARIABLES ==========================================================*/
|
||||
|
||||
/* PROTOTYPES ================================================================*/
|
||||
|
||||
/* FUNCTIONS =================================================================*/
|
||||
|
||||
/**
|
||||
* Obtiain and store current time in a string buffer in ISO format
|
||||
*
|
||||
* @param buf char* buffer to store ISO string representation of current time
|
||||
* @param len int length of buffer to not exceed
|
||||
* @return returns a pointer to buffer for convenience
|
||||
*/
|
||||
char *isotime(char *buf, int len)
|
||||
{
|
||||
time_t t;
|
||||
struct tm tm;
|
||||
|
||||
// Gets the gurrent UTC time in seconds
|
||||
t = time(NULL);
|
||||
|
||||
// Convert time into struct tm format
|
||||
gmtime_r(&t, &tm);
|
||||
|
||||
// Store time in string buffer in ISO format
|
||||
strftime(buf, len, "%F %T", &tm);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two timespec values
|
||||
*
|
||||
* @param a struct timespec*
|
||||
* @param b struct timespec*
|
||||
* @param result struct timespec*
|
||||
*/
|
||||
void timespec_add(struct timespec *a, struct timespec *b, struct timespec *result)
|
||||
{
|
||||
result->tv_sec = a->tv_sec + b->tv_sec;
|
||||
result->tv_nsec = a->tv_nsec + b->tv_nsec;
|
||||
timespec_norm(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a timespec into another
|
||||
*
|
||||
* @param dst struct timespec*
|
||||
* @param src struct timespec*
|
||||
*/
|
||||
void timespec_copy(struct timespec *dst, struct timespec *src)
|
||||
{
|
||||
dst->tv_sec = src->tv_sec;
|
||||
dst->tv_nsec = src->tv_nsec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare timespec a and b. Return which is greater.
|
||||
*
|
||||
* Behavior is undefined if lhs or rhs are not pointers to null-terminated byte strings.
|
||||
*
|
||||
* @return 1 : lhs > rhs
|
||||
* 0 : lhs = rhs
|
||||
* -1 : lhs < rhs
|
||||
*/
|
||||
int timespec_cmp(struct timespec *lhs, struct timespec *rhs)
|
||||
{
|
||||
struct timespec A, B;
|
||||
int rv;
|
||||
|
||||
rv = 0;
|
||||
|
||||
// Copy into local varaibles and normalize as we cannot modify input parameters
|
||||
timespec_set(&A, lhs->tv_sec, lhs->tv_nsec);
|
||||
timespec_set(&B, rhs->tv_sec, rhs->tv_nsec);
|
||||
|
||||
if (A.tv_sec > B.tv_sec)
|
||||
rv = 1;
|
||||
else if (A.tv_sec < B.tv_sec)
|
||||
rv = -1;
|
||||
else
|
||||
{
|
||||
if (A.tv_nsec > B.tv_nsec)
|
||||
rv = 1;
|
||||
else if (A.tv_nsec < B.tv_nsec)
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute difference between timespec a and b. Result = a - b
|
||||
*
|
||||
* Result will be normalized. Input parameters are not modified
|
||||
*
|
||||
* @param a struct timespec*
|
||||
* @param b struct timespec*
|
||||
* @param result struct timespec*
|
||||
*/
|
||||
void timespec_diff(struct timespec *a, struct timespec *b, struct timespec *result)
|
||||
{
|
||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||
result->tv_nsec = a->tv_nsec - b->tv_nsec;
|
||||
timespec_norm(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a time specified has elapsed
|
||||
*
|
||||
* @param t struct timespec* the time to test
|
||||
* @param cid Clock ID to determine current time. If <0 use CLOCK_MONOTONIC
|
||||
* @return 1 if time has past, 0 if it has not
|
||||
*/
|
||||
int timespec_elapsed(struct timespec* t, clockid_t cid)
|
||||
{
|
||||
struct timespec now;
|
||||
int rv;
|
||||
|
||||
// Initialize variables
|
||||
rv = 0;
|
||||
if (cid < 0)
|
||||
cid = CLOCK_MONOTONIC;
|
||||
clock_gettime(cid, &now);
|
||||
|
||||
// Compare provided time to now
|
||||
rv = timespec_cmp(&now, t);
|
||||
|
||||
// bound rv to 0 or 1
|
||||
if (rv < 0)
|
||||
rv = 0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a timespec object to standard time form
|
||||
*
|
||||
* Rounds tv_nsec to be between 0 - 1B nano seconds
|
||||
|
||||
* @param t struct timespec* to normalize
|
||||
*/
|
||||
void timespec_norm(struct timespec *t)
|
||||
{
|
||||
if (t->tv_nsec >= 1000000000)
|
||||
{
|
||||
t->tv_sec += (t->tv_nsec / 1000000000);
|
||||
t->tv_nsec %= 1000000000;
|
||||
}
|
||||
else if (t->tv_nsec < 0)
|
||||
{
|
||||
t->tv_sec -= ((t->tv_nsec / -1000000000) + 1);
|
||||
t->tv_nsec %= 1000000000;
|
||||
if (t->tv_nsec < 0)
|
||||
t->tv_nsec += 1000000000;
|
||||
else if (t->tv_nsec == 0)
|
||||
t->tv_sec += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a timespec object
|
||||
*
|
||||
* @param t struct timespec*
|
||||
*/
|
||||
void timespec_print(struct timespec *t)
|
||||
{
|
||||
printf("timespec: %ld:%ld\n", t->tv_sec, t->tv_nsec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill and normalize a timespec object
|
||||
*
|
||||
* @param t struct timespec* to fill
|
||||
* @param sec time_t of seconds to set
|
||||
* @param nsec long of nanoseconds to use
|
||||
*/
|
||||
void timespec_set(struct timespec *t, time_t sec, long nsec)
|
||||
{
|
||||
t->tv_sec = sec;
|
||||
t->tv_nsec = nsec;
|
||||
timespec_norm(t);
|
||||
}
|
||||
|
||||
|
||||
44
main.h
Normal file
44
main.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/**
|
||||
* @file timeutils.h
|
||||
*
|
||||
* @brief Header file for Time Utils Library
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
*
|
||||
* @date Mar 2024
|
||||
* @author Barrett Edwards <code@jrlabs.io>
|
||||
*
|
||||
* Macro / Enumeration Prefixes
|
||||
*/
|
||||
|
||||
#ifndef _TIMEUTILS_H
|
||||
#define _TIMEUTILS_H
|
||||
|
||||
/* INCLUDES ==================================================================*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* MACROS ====================================================================*/
|
||||
|
||||
/* ENUMERATIONS ==============================================================*/
|
||||
|
||||
/* STRUCTS ===================================================================*/
|
||||
|
||||
/* GLOBAL VARIABLES ==========================================================*/
|
||||
|
||||
/* PROTOTYPES ================================================================*/
|
||||
|
||||
char *isotime(char *buf, int len);
|
||||
void timespec_add(struct timespec *a, struct timespec *b, struct timespec *result);
|
||||
void timespec_copy(struct timespec *dst, struct timespec *src);
|
||||
int timespec_cmp(struct timespec *lhs, struct timespec *rhs);
|
||||
void timespec_diff(struct timespec *a, struct timespec *b, struct timespec *result);
|
||||
int timespec_elapsed(struct timespec* t, clockid_t cid);
|
||||
void timespec_norm(struct timespec *t);
|
||||
void timespec_print(struct timespec *t);
|
||||
void timespec_set(struct timespec *t, time_t sec, long nsec);
|
||||
|
||||
/* INLINE FUNCTIONS ==========================================================*/
|
||||
|
||||
#endif //ifndef _TIMEUTILS_H
|
||||
228
testbench.c
Normal file
228
testbench.c
Normal file
@ -0,0 +1,228 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/**
|
||||
* @file testbench.c
|
||||
*
|
||||
* @brief Testbench code file for Time Utils library
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
*
|
||||
* @date Mar 2024
|
||||
* @author Barrett Edwards <code@jrlabs.io>
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDES ==================================================================*/
|
||||
|
||||
/* printf()
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
/* timespec
|
||||
*/
|
||||
#include <time.h>
|
||||
|
||||
#include "timeutils.h"
|
||||
|
||||
/* MACROS ====================================================================*/
|
||||
|
||||
/* ENUMERATIONS ==============================================================*/
|
||||
|
||||
/* STRUCTS ===================================================================*/
|
||||
|
||||
/* GLOBAL VARIABLES ==========================================================*/
|
||||
|
||||
/* PROTOTYPES ================================================================*/
|
||||
|
||||
/* FUNCTIONS =================================================================*/
|
||||
|
||||
int main()
|
||||
{
|
||||
struct timespec a, b, c;
|
||||
int rv;
|
||||
|
||||
printf("Add two time specs-------------------\n");
|
||||
timespec_set(&a, 10, 17);
|
||||
timespec_set(&b, 23, 11);
|
||||
timespec_add(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nAdd two time specs-------------------\n");
|
||||
timespec_set(&a, -10, 17);
|
||||
timespec_set(&b, 23, -11);
|
||||
timespec_add(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nAdd two time specs-------------------\n");
|
||||
timespec_set(&a, -10, -17);
|
||||
timespec_set(&b, 23, -11);
|
||||
timespec_add(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nAdd two time specs-------------------\n");
|
||||
timespec_set(&a, 10, 999999999);
|
||||
timespec_set(&b, 23, 11);
|
||||
timespec_add(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nAdd two time specs-------------------\n");
|
||||
timespec_set(&a, 10, 1000000001);
|
||||
timespec_set(&b, 23, 1000000001);
|
||||
timespec_add(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nAdd two time specs-------------------\n");
|
||||
timespec_set(&a, 10, -1000000001);
|
||||
timespec_set(&b, 23, -1000000001);
|
||||
timespec_add(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nAdd two time specs-------------------\n");
|
||||
timespec_set(&a, 10, 4000000001);
|
||||
timespec_set(&b, 23, 4000000001);
|
||||
timespec_add(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\ncmp two time specs-------------------\n");
|
||||
timespec_set(&a, 10, 1);
|
||||
timespec_set(&b, 10, 1);
|
||||
rv = timespec_cmp(&a, &b);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
printf("rv = %d\n", rv);
|
||||
|
||||
printf("\ncmp two time specs-------------------\n");
|
||||
timespec_set(&a, 10, 1);
|
||||
timespec_set(&b, 11, 1);
|
||||
rv = timespec_cmp(&a, &b);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
printf("rv = %d\n", rv);
|
||||
|
||||
printf("\ncmp two time specs-------------------\n");
|
||||
timespec_set(&a, 11, 1);
|
||||
timespec_set(&b, 10, 1);
|
||||
rv = timespec_cmp(&a, &b);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
printf("rv = %d\n", rv);
|
||||
|
||||
printf("\ncmp two time specs-------------------\n");
|
||||
timespec_set(&a, 10, 1);
|
||||
timespec_set(&b, 10, 2);
|
||||
rv = timespec_cmp(&a, &b);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
printf("rv = %d\n", rv);
|
||||
|
||||
printf("\ncmp two time specs-------------------\n");
|
||||
timespec_set(&a, 10, 2);
|
||||
timespec_set(&b, 10, 1);
|
||||
rv = timespec_cmp(&a, &b);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
printf("rv = %d\n", rv);
|
||||
|
||||
printf("\ncmp two time specs-------------------\n");
|
||||
timespec_set(&a, 11, 1);
|
||||
timespec_set(&b, 10, 1000000002);
|
||||
rv = timespec_cmp(&a, &b);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
printf("rv = %d\n", rv);
|
||||
|
||||
printf("\nDiff two time specs-------------------\n");
|
||||
timespec_set(&a, 23, 1);
|
||||
timespec_set(&b, 10, 1);
|
||||
timespec_diff(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nDiff two time specs-------------------\n");
|
||||
timespec_set(&a, 23, 1);
|
||||
//timespec_set(&b, 10, 1000000001);
|
||||
b.tv_sec = 10; b.tv_nsec = 1000000001;
|
||||
timespec_diff(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nDiff two time specs-------------------\n");
|
||||
//timespec_set(&a, 23, 1);
|
||||
a.tv_sec = 23; a.tv_nsec = 2000000001;
|
||||
//timespec_set(&b, 10, 1000000001);
|
||||
b.tv_sec = 10; b.tv_nsec = 1000000001;
|
||||
timespec_diff(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nDiff two time specs-------------------\n");
|
||||
timespec_set(&a, 0, 0);
|
||||
//timespec_set(&b, 10, 1000000001);
|
||||
b.tv_sec = 10; b.tv_nsec = 1000000001;
|
||||
timespec_diff(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nDiff two time specs-------------------\n");
|
||||
timespec_set(&a, 0, 0);
|
||||
//timespec_set(&b, 10, 1000000001);
|
||||
b.tv_sec = 10; b.tv_nsec = 2000000001;
|
||||
timespec_diff(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nDiff two time specs-------------------\n");
|
||||
timespec_set(&a, -1, 0);
|
||||
timespec_set(&b, -10, 2000000001);
|
||||
//b.tv_sec = -10; b.tv_nsec = 2000000001;
|
||||
timespec_diff(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nDiff two time specs-------------------\n");
|
||||
timespec_set(&a, -1, 0);
|
||||
timespec_set(&b, -10, -2000000001);
|
||||
//b.tv_sec = -10; b.tv_nsec = 2000000001;
|
||||
timespec_diff(&a, &b, &c);
|
||||
timespec_print(&a);
|
||||
timespec_print(&b);
|
||||
timespec_print(&c);
|
||||
|
||||
printf("\nCompare two time specs-------------------\n");
|
||||
clock_gettime(CLOCK_MONOTONIC, &a);
|
||||
clock_gettime(CLOCK_MONOTONIC, &b);
|
||||
printf("timespec_cmp(a,b): %d\n", timespec_cmp(&a,&b));
|
||||
printf("timespec_cmp(b,a): %d\n", timespec_cmp(&b,&a));
|
||||
printf("timespec_cmp(a,a): %d\n", timespec_cmp(&a,&a));
|
||||
|
||||
printf("\nTest if time has elapsed ----------------\n");
|
||||
clock_gettime(CLOCK_MONOTONIC, &a);
|
||||
a.tv_sec += 5;
|
||||
printf("timespec_elapsed(a): %d\n", timespec_elapsed(&a,-1));
|
||||
|
||||
printf("\nTest if time has elapsed ----------------\n");
|
||||
clock_gettime(CLOCK_MONOTONIC, &a);
|
||||
a.tv_sec -= 5;
|
||||
printf("timespec_elapsed(a): %d\n", timespec_elapsed(&a,-1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user