Release candidate

This commit is contained in:
Grant Mackey 2024-04-02 05:01:30 +00:00
parent 47ebc07264
commit bf96e32fe6
5 changed files with 3273 additions and 0 deletions

2733
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

52
Makefile Normal file
View 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
View 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
View 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
View 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;
}