Merge branch 'dev'
This commit is contained in:
+2
-10
@@ -1,5 +1,5 @@
|
||||
#ifndef BITEVEC_H_
|
||||
#define BITEVEC_H_
|
||||
#ifndef UC_BITEVEC_H_
|
||||
#define UC_BITEVEC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -65,14 +65,6 @@ void uc_bv_set_all(struct UCBitVec *v);
|
||||
* */
|
||||
void uc_bv_set_bits_from_array(struct UCBitVec *v,char *array,size_t array_len);
|
||||
|
||||
// The _s ("secure") versions does boundary checking and assert() if they
|
||||
// try to access a bit out of bounds.
|
||||
|
||||
void uc_bv_set_bit_s(struct UCBitVec *v,int b);
|
||||
|
||||
void uc_bv_clear_bit_s(struct UCBitVec *v,int b);
|
||||
|
||||
int uc_bv_get_bit_s(const struct UCBitVec *v,int b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_BUFFER_H_
|
||||
#define UCORE_BUFFER_H_
|
||||
#ifndef UC_BUFFER_H_
|
||||
#define uc_BUFFER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef dbuf_H_
|
||||
#define dbuf_H_
|
||||
#ifndef UC_DBUF_H_
|
||||
#define UC_DBUF_H_
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef FD_UTILS_H_
|
||||
#define FD_UTILS_H_
|
||||
#ifndef UC_FD_UTILS_H_
|
||||
#define UC_FD_UTILS_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_HASH_H_
|
||||
#define UCORE_HASH_H_
|
||||
#ifndef UC_HASH_H_
|
||||
#define UC_HASH_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_HEAPSORT_H_
|
||||
#define UCORE_HEAPSORT_H_
|
||||
#ifndef UC_HEAPSORT_H_
|
||||
#define UC_HEAPSORT_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
#ifndef UC_HTABLE_H_
|
||||
#define UC_HTABLE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/** Building block for hash table.
|
||||
* The hash table is stored using a chained list of buckets.
|
||||
* Nodes with different hash value can be stored in the same bucket.
|
||||
*
|
||||
*
|
||||
* The hash table manages only the hash value, not the equality
|
||||
* between nodes.
|
||||
*
|
||||
* It's up to the user to check for duplicate values
|
||||
* before adding nodes if dublicates are not desired.
|
||||
*
|
||||
* Finding a node must be done in a user specific way,
|
||||
* normally by iterating over all nodes with the desidred
|
||||
* hash, and deciding in some other way whether it is the desidred
|
||||
* node.
|
||||
*/
|
||||
|
||||
/** Node the hashtable tracks.
|
||||
* Will normally be embedded inside another struct
|
||||
*/
|
||||
struct UHNode {
|
||||
//cached value of the hash
|
||||
size_t hash;
|
||||
//pointer to next in same bucket
|
||||
struct UHNode *next;
|
||||
};
|
||||
|
||||
/**
|
||||
* The hash table struct
|
||||
*/
|
||||
struct UHTable {
|
||||
size_t cnt_elements;
|
||||
size_t cnt_buckets;
|
||||
struct UHNode **buckets;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a hash table.
|
||||
* @param table hash table to initialize
|
||||
* @param buckets number of buckets
|
||||
* @return 0 on success, errno if malloc fails or buckets == 0
|
||||
*/
|
||||
int uc_htable_init(struct UHTable *table, size_t buckets);
|
||||
|
||||
/**
|
||||
* Free resources of the hash table.
|
||||
* @param table hash table to free (does not free @table itself
|
||||
*/
|
||||
void uc_htable_destroy(struct UHTable *table);
|
||||
|
||||
|
||||
/**
|
||||
* @param table
|
||||
* @param hash find the bucket from this hash value
|
||||
* @return the bucket number for the given hash
|
||||
*/
|
||||
static inline size_t uc_htable_bucket(const struct UHTable *table, size_t hash)
|
||||
{
|
||||
return hash % table->cnt_buckets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first bucket node for the given hash.
|
||||
* The returned node might not have the same hash, since different
|
||||
* nodes can share the same bucket.
|
||||
*
|
||||
* @param table table
|
||||
* @param hash hash
|
||||
*/
|
||||
static inline struct UHNode *uc_htable_first_bucket(const struct UHTable *table, size_t hash)
|
||||
{
|
||||
size_t bucket = uc_htable_bucket(table, hash);
|
||||
|
||||
return table->buckets[bucket];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next node in the bucket.
|
||||
* @return next node or NULL
|
||||
*/
|
||||
static inline struct UHNode *uc_htable_next_bucket(const struct UHNode *node)
|
||||
{
|
||||
return node->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first node that have the given hash
|
||||
* @param table table
|
||||
* @param hash hash
|
||||
* @return first node with the given hash or NULL
|
||||
*/
|
||||
struct UHNode *uc_htable_first_hash(const struct UHTable *table, size_t hash);
|
||||
|
||||
|
||||
//internal helper
|
||||
struct UHNode *uc_htable_next_hash_hlp(struct UHNode *next, size_t hash);
|
||||
|
||||
/**
|
||||
* Get the next node with the same hash
|
||||
* @param node previous node
|
||||
* @return next node with the same hash as node or NULL
|
||||
*/
|
||||
static inline struct UHNode *uc_htable_next_hash(const struct UHNode *node)
|
||||
{
|
||||
return uc_htable_next_hash_hlp(node->next, node->hash);
|
||||
}
|
||||
|
||||
|
||||
//internal helper
|
||||
struct UHNode *uc_htable_iter_hlp(struct UHTable *table, size_t bucket);
|
||||
|
||||
/** Get the first node in the hash table
|
||||
*
|
||||
* @param table table
|
||||
* @return first node or NULL
|
||||
*/
|
||||
static inline struct UHNode *uc_htable_first(struct UHTable *table)
|
||||
{
|
||||
return uc_htable_iter_hlp(table, 0);
|
||||
}
|
||||
|
||||
/** Get the next node in the hash table
|
||||
*
|
||||
* @param table table
|
||||
* @param node previous node
|
||||
* @return first node or NULL
|
||||
*/
|
||||
struct UHNode *uc_htable_next(struct UHTable *table, struct UHNode *node);
|
||||
|
||||
/**
|
||||
* Swap 2 hash tables.
|
||||
*
|
||||
* @param a first table
|
||||
* @param b second table
|
||||
*/
|
||||
void uc_htable_swap(struct UHTable *a, struct UHTable *b);
|
||||
|
||||
/**
|
||||
* Iterate over all nodes in a bucket.
|
||||
* The table must not be changed while iterating.
|
||||
*
|
||||
* @param table the struct UHTable*
|
||||
* @param node_iter struct UHNode* for the current node being iterated
|
||||
* @param hash size_t hash for the bucket to iterate
|
||||
*/
|
||||
#define UC_HTABLE_FOREACH_BUCKET(table, node_iter, hash)\
|
||||
for ((node_iter) = uc_htable_first_bucket((table), (hash));\
|
||||
(node_iter) != NULL;\
|
||||
(node_iter) = uc_htable_next_bucket((node_iter)))
|
||||
|
||||
/**
|
||||
* Iterate over all nodes that has the given hash.
|
||||
* The table must not be changed while iterating.
|
||||
* Normally the user would check in a user specific way
|
||||
* if the node_iter is equal to the node one wants to find.
|
||||
*
|
||||
* @param table the struct UHTable*
|
||||
* @param node_iter struct UHNode* for the current node being iterated
|
||||
* @param hash size_t hash for the node(s) to iterate over
|
||||
*/
|
||||
#define UC_HTABLE_FOREACH_HASH(table, node_iter, hash)\
|
||||
for ((node_iter) = uc_htable_first_hash((table), (hash));\
|
||||
(node_iter) != NULL;\
|
||||
(node_iter) = uc_htable_next_hash((node_iter)))
|
||||
|
||||
/**
|
||||
* "Safe" variant of UC_HTABLE_FOREACH_HASH, the iterated node
|
||||
* (or any previously iterated nodes) can be freed while iterating
|
||||
*
|
||||
* @param table the struct UHTable*
|
||||
* @param node_iter struct UHNode* for the current node being iterated
|
||||
* @param next_iter struct UHNode* for the next node, required by the
|
||||
* iteration, next_iter must not be altered while iterating.
|
||||
* @param hash size_t hash for the node(s) to iterate over
|
||||
*/
|
||||
#define UC_HTABLE_FOREACH_HASH_SAFE(table, node_iter, next_iter, hash)\
|
||||
for ((node_iter) = uc_htable_first_hash((table), (hash));\
|
||||
(node_iter) != NULL && (((next_iter) = (node_iter->next)), 1);\
|
||||
(node_iter) = (next))
|
||||
|
||||
/**
|
||||
* Iterate over all nodes in a table
|
||||
* The table must not be changed while iterating.
|
||||
*
|
||||
* @param table the struct UHTable*
|
||||
* @param node_iter struct UHNode* for the current node being iterated
|
||||
*/
|
||||
#define UC_HTABLE_FOREACH(table, node_iter)\
|
||||
for ((node_iter) = uc_htable_first((table));\
|
||||
(node_iter) != NULL;\
|
||||
(node_iter) = uc_htable_next((table), (node_iter)))
|
||||
|
||||
/**
|
||||
* "Safe" variant of UC_HTABLE_FOREACH, the iterated node
|
||||
* (or any previously iterated nodes) can be freed while iterating
|
||||
*
|
||||
* @param table the struct UHTable*
|
||||
* @param node_iter struct UHNode* for the current node being iterated
|
||||
* @param next_iter struct UHNode* for the next node, required by the
|
||||
* iteration, next_iter must not be altered while iterating.
|
||||
*/
|
||||
#define UC_HTABLE_FOREACH_SAFE(table, node_iter, next_iter)\
|
||||
for ((node_iter) = uc_htable_first((table));\
|
||||
(node_iter) != NULL &&\
|
||||
((next_iter) = uc_htable_next((table), (node_iter)), 1);\
|
||||
(node_iter) = (next))
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given node pointer exists in the hash table
|
||||
*
|
||||
* @param table table
|
||||
* @param node node to check for
|
||||
* @return 0 if the node does not exist in table non-0 if it does
|
||||
*/
|
||||
int uc_htable_has_node(struct UHTable *table, struct UHNode *node);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return 0 if table is empty non-0 if it contains any nodes
|
||||
*/
|
||||
static inline int uc_htable_isempty(const struct UHTable *table)
|
||||
{
|
||||
return table->cnt_elements == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of elements in the hash table.
|
||||
*
|
||||
* @rparam table table
|
||||
* @return number of elements
|
||||
*/
|
||||
static inline size_t uc_htable_count(const struct UHTable *table)
|
||||
{
|
||||
return table->cnt_elements;
|
||||
}
|
||||
|
||||
/** Clears all nodes from the hash table, making it empty.
|
||||
* No memory is released.
|
||||
* @param table table to clear
|
||||
*/
|
||||
void uc_htable_clear(struct UHTable *table);
|
||||
|
||||
/** Insert a new node.
|
||||
* The new node pointer must exist as long as it is part of the
|
||||
* hash table. The hash table does not check for duplicates in any way.
|
||||
*
|
||||
* @param table table to insert into
|
||||
* @param node new node to insert.
|
||||
* @param hash hash value of the new node
|
||||
*/
|
||||
void uc_htable_insert(struct UHTable *table, struct UHNode *node, size_t hash);
|
||||
|
||||
/** Remove a node.
|
||||
* If the node pointer is not part of the table,
|
||||
* no action is taken
|
||||
*
|
||||
* @param table table to remove from.
|
||||
* @param node node to remove.
|
||||
*/
|
||||
void uc_htable_remove(struct UHTable *table, struct UHNode *node);
|
||||
|
||||
/** Resize the hash table. This changes the number of buckets, and re-inserts
|
||||
* all nodes.
|
||||
*
|
||||
* @param table table to resize
|
||||
* @param buckets new number of buckets, must be > 0
|
||||
* @return 0 on success, errno if malloc fails or buckets == 0
|
||||
*/
|
||||
int uc_htable_resize(struct UHTable *table, size_t buckets);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef IO_MUX_H_
|
||||
#define IO_MUX_H_
|
||||
#ifndef UC_IO_MUX_H_
|
||||
#define UC_IO_MUX_H_
|
||||
|
||||
#include "timers.h"
|
||||
/** @addtogroup IOMux
|
||||
|
||||
+12
-9
@@ -1,5 +1,6 @@
|
||||
#ifndef UCORE_LOGGING_H_
|
||||
#define UCORE_LOGGING_H_
|
||||
#ifndef UC_LOGGING_H_
|
||||
#define UC_LOGGING_H_
|
||||
#include "utils.h"
|
||||
|
||||
/** Logging functions.
|
||||
* All logging functions except uc_log_init are thread safe,
|
||||
@@ -268,14 +269,16 @@ int uc_log_reopen_files(void);
|
||||
void uc_log_init(struct uc_log_modules *user_modules);
|
||||
|
||||
void uc_logf(int log_level, int module, int raw,
|
||||
const char *file, int line, const char *fmt, ...)
|
||||
__attribute__((format(printf, 6, 7)));
|
||||
const char *location, const char *fmt, ...)
|
||||
__attribute__((format(printf, 5, 6)));
|
||||
|
||||
#ifdef DEBUG
|
||||
// only compile in UC_DEBUG log calls in debug mode, but allow the user
|
||||
// to override that by defining UC_DEBUG_ALWAYS
|
||||
#if defined(DEBUG) || defined(UC_DEBUG_ALWAYS)
|
||||
# define UC_DEBUGF(mod, fmt, ...)\
|
||||
uc_logf(UC_LL_DEBUG, mod,0 , __FILE__, __LINE__, fmt, ## __VA_ARGS__)
|
||||
uc_logf(UC_LL_DEBUG, mod,0 , UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
||||
# define UC_DEBUGFR(mod, fmt, ...)\
|
||||
uc_logf(UC_LL_DEBUG, mod,1 , __FILE__, __LINE__, fmt, ## __VA_ARGS__)
|
||||
uc_logf(UC_LL_DEBUG, mod,1 , UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
# define UC_DEBUGF(mod, fmt, ...)
|
||||
# define UC_DEBUGFR(mod, fmt, ...)
|
||||
@@ -292,14 +295,14 @@ void uc_logf(int log_level, int module, int raw,
|
||||
* @param ... printf style arguments
|
||||
*/
|
||||
#define UC_LOGF(lvl, mod, fmt, ...) \
|
||||
uc_logf(lvl, mod, 0, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
|
||||
uc_logf(lvl, mod, 0, UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
||||
|
||||
|
||||
/** Raw logging ,Like UC_LOGF, but only prints the supplied
|
||||
* data, not timestamp, log level etc.
|
||||
*/
|
||||
#define UC_LOGFR(lvl, mod, fmt, ...) \
|
||||
uc_logf(lvl, mod, 1, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
|
||||
uc_logf(lvl, mod, 1, UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_MATH_H_
|
||||
#define UCORE_MATH_H_
|
||||
#ifndef UC_MATH_H_
|
||||
#define UC_MATH_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ struct MBuf {
|
||||
/**Arbitary pointer user can associate with the mbuf*/
|
||||
void *cookie;
|
||||
|
||||
/*UC_MBUF_FLAGS. The upper 16 bits can be used by the application */
|
||||
uint32_t flags;
|
||||
/** Total no of bytes from bufstart*/
|
||||
uint32_t allocated;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_MERSENNE_TWISTER_H
|
||||
#define UCORE_MERSENNE_TWISTER_H
|
||||
#ifndef UC_MERSENNE_TWISTER_H
|
||||
#define UC_MERSENNE_TWISTER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_PACK_H_
|
||||
#define UCORE_PACK_H_
|
||||
#ifndef UC_PACK_H_
|
||||
#define UC_PACK_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef __GNUC__
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
#ifndef UC_RATE_LIMIT_H_
|
||||
#define UC_RATE_LIMIT_H_
|
||||
|
||||
/** This is a rate limiter, based on the token bucket principle.
|
||||
* We have X amount of tickets(=our rate) per Y amount of time,
|
||||
*
|
||||
* The allowed tickets increases with X per Y amount of time.
|
||||
*
|
||||
* Bursts will be allowed up till the number of tickets initially
|
||||
* specified.
|
||||
* e.g. if we are limited to 50 tickets * per 2 second, 50 tickets
|
||||
* can be immedietely handed out in the
|
||||
* first second. At the 2. second, 25 more tickets become available
|
||||
* handed out, at the 3. second 25 more, and so on.
|
||||
* (So this is throttleed, so no more than the initial tickets, 50 in
|
||||
* this case, can be handed out in any given period)
|
||||
*
|
||||
* Another example is if we rate 1000 tickets per 60 seconds,
|
||||
* 1000 tickets can be handed out the 1. second, 16/17 more the
|
||||
* next second, 16/17 more the 3. second and so on.
|
||||
*
|
||||
* Specify how many tickes we have available per period of time.
|
||||
* when work is performed, call uc_ratelimit_cllow() with the current
|
||||
* time.
|
||||
* The unit of time passed to uc_ratelimit_allow must be the same as
|
||||
* for uc_ratelimit_init.
|
||||
*
|
||||
* Example for rate limiting accepting connections:
|
||||
* struct RateLimit r;
|
||||
* //Limit to 20 per 1 second, which also limits us to max 20
|
||||
* per second. (1 second since we will pass in time that have 1 second resolution)
|
||||
* 40 per 2 second would even out to the same rate, but allow a burst of 40
|
||||
* (if there's 40 tickets available)
|
||||
*
|
||||
* uc_ratelimit_init(&r,20, 1, time(NULL));
|
||||
*
|
||||
* NOTE. (period + 1) * tickets must not exceed the range of the RateLimit.funds
|
||||
*
|
||||
* for (;;) {
|
||||
* int fd = accept(..);
|
||||
* if (uc_ratelimit_allow(&r, time(NULL)) {
|
||||
* //handle new connection
|
||||
* } else {
|
||||
* //exceeded limit
|
||||
* close(fd);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
struct RateLimit {
|
||||
//how many tickets we want
|
||||
long tickets;
|
||||
//per this period of time
|
||||
long period;
|
||||
|
||||
//internal fields:
|
||||
|
||||
//money we have to "buy" tickets
|
||||
long funds;
|
||||
//time of the previos period
|
||||
long last_ts;
|
||||
};
|
||||
|
||||
/** Static initializer for a struct RateLimit
|
||||
*
|
||||
* @param tickets number of tickets (bucket depth)
|
||||
* @param period per this period
|
||||
*/
|
||||
#define UC_RATELIMIT_INITIALIZER(tickets)\
|
||||
{ tickets, period, 0, -period}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a struct RateLimit, which can hand out @tickets per @period
|
||||
* the perioid must be in the same units as the current_ts
|
||||
*
|
||||
* NOTE. 2 * (period + 1) * tickets must not exceed the range of the RateLimit.funds
|
||||
*
|
||||
* @param r RateLimit to initialize
|
||||
* @param tickets number of tickets (bucket depth)
|
||||
* @param period per this period
|
||||
*/
|
||||
void uc_ratelimit_init(struct RateLimit *r, long tickets, long period);
|
||||
|
||||
/**
|
||||
* Reset a RateLimit, filling up the tickets again.
|
||||
*
|
||||
* @param r RateLimit to reset
|
||||
* @param current ts, if non-zero, re-sets the last_ts to the current_ts
|
||||
*/
|
||||
void uc_ratelimit_reset(struct RateLimit *r, long current_ts);
|
||||
|
||||
/**
|
||||
* Check if we have 1 ticket available, and can therefore allow
|
||||
* the work. Removes 1 ticket if we can, and replenishes the tickets
|
||||
* based on the elapsed time since last time the function was called.
|
||||
*
|
||||
* @param r the RateLimit
|
||||
* @param current_ts the current timestamp. Used to calculate the
|
||||
* replenisment of tichets since the previous check.
|
||||
* @return 1 if we can allow, 0 if we don't.
|
||||
*/
|
||||
int uc_ratelimit_allow(struct RateLimit *r, long current_ts);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef RBTREE_H_
|
||||
#define RBTREE_H_
|
||||
#ifndef UC_RBTREE_H_
|
||||
#define UC_RBTREE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_READ_FILE_H_
|
||||
#define UCORE_READ_FILE_H_y
|
||||
#ifndef UC_READ_FILE_H_
|
||||
#define UC_READ_FILE_H_y
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef SALLOC_H_
|
||||
#define SALLOC_H_
|
||||
#ifndef UC_SALLOC_H_
|
||||
#define UC_SALLOC_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifndef UC_SATMATH_H_
|
||||
#define UC_SATMATH_H_
|
||||
#include <stdint.h>
|
||||
|
||||
/** Implementation of saturated operation on uintxx_t.
|
||||
@@ -79,3 +81,4 @@ static inline uint64_t uc_sat_multu64(uint64_t a, uint64_t b)
|
||||
return UC_SAT_MULT(a, b, uint64_t, UINT64_MAX);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef SEQ_H_
|
||||
#define SEQ_H_
|
||||
#ifndef UC_SEQ_H_
|
||||
#define UC_SEQ_H_
|
||||
#include <stdint.h>
|
||||
|
||||
// Check if a is less than b, taking care of wrap arounds
|
||||
|
||||
+39
-4
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_STRING_H_
|
||||
#define UCORE_STRING_H_
|
||||
#ifndef UC_STRING_H_
|
||||
#define UC_STRING_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -17,16 +17,48 @@ uc_hex_decode(const char *in, size_t maxlen,uint8_t *out);
|
||||
char*
|
||||
uc_hex_encode_delim(const uint8_t *in, size_t inlen, char *out, int outlen, char *delim);
|
||||
|
||||
/**
|
||||
* Convert the string to lowercase, calls tolower() on each char.
|
||||
* @param s string to lowercase
|
||||
*/
|
||||
void
|
||||
uc_str_tolower(char *s);
|
||||
/**
|
||||
* Convert the string to uppercase, calls toupper() on each char.
|
||||
* @param s string to uppercase
|
||||
*/
|
||||
void
|
||||
uc_str_toupper(char *s);
|
||||
|
||||
/** Macro to calculate the number of bytes required to BCD encode
|
||||
* the number of ascii digits
|
||||
*/
|
||||
#define UC_BCD_LEN(ascii_len) ((ascii_len) / 2 + ((ascii_len) % 2))
|
||||
#define UC_ASCII_LEN(bcd_len) ((bcd_len) * 2 + 1)
|
||||
|
||||
/** Macro to calculate the number of bytes required to ASCII encode
|
||||
* the number of BCD digits
|
||||
*/
|
||||
#define UC_ASCII_LEN(bcd_len) ((bcd_len) * 2)
|
||||
|
||||
/** Convert the ascii digits to BCD. Digits not in 0..9 are skipped.
|
||||
*
|
||||
* @param ascii string to BCD encode.
|
||||
* @param bcdout resulting BCD data. Must be at least UC_BCD_LEN(strlen(asciii)) big
|
||||
* @param filler filler byte(not the ascii digit) to write in the last BCD nibble
|
||||
* if the number of ASCII digits is odd. This would usually be 0x0 or 0xf.
|
||||
* @return the number of bytes written to bcdout
|
||||
*/
|
||||
size_t
|
||||
uc_ascii2bcd(const char *ascii, unsigned char *bcdout, unsigned char filler);
|
||||
|
||||
/** Convert the BCD digits to ascii.
|
||||
* The resulting ascii string is 0 terminated.
|
||||
*
|
||||
* @param bcd Buffer with BCD data to convert to ascii
|
||||
* @param bcdlen number of bytes in @bcd to convert
|
||||
* @param asciiout buffer to place ASCII in, must be UC_ASCII_LEN(bcdlen)+1 big
|
||||
* @return the number of characters written to bcdout (this will always be UC_ASCII_LEN(bcdlen)
|
||||
*/
|
||||
size_t
|
||||
uc_bcd2ascii(const unsigned char *bcd, size_t bcdlen, char *asciiout);
|
||||
|
||||
@@ -39,10 +71,13 @@ uc_sprintbll(char *result, unsigned long long value);
|
||||
char*
|
||||
uc_sprintbs(char *result, unsigned short value);
|
||||
|
||||
/** Like http://swtch.com/plan9port/man/man3/getfields.html
|
||||
*/
|
||||
int
|
||||
getfields(char *str, char **args, int max, int mflag, const char *set);
|
||||
|
||||
//ocnvert bytes to a human representable test, (i.e. 12kB, 160 MB 1.78 GB etc.
|
||||
//Converts bytes to a human representable test, (i.e. 12kB, 160 MB 1.78 GB etc.)
|
||||
//Conversion is done in decimal (base 10 ,1 kB == 1000 bytes)
|
||||
///result should be at least of size 12,
|
||||
///returns the result argument
|
||||
char *
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef UC_STRVEC_H_
|
||||
#define UC_STRVEC_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_SUPERVISOR_H_
|
||||
#define UCORE_SUPERVISOR_H_
|
||||
#ifndef UC_SUPERVISOR_H_
|
||||
#define UC_SUPERVISOR_H_
|
||||
|
||||
/** Supervises this process - restart if it dies.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _THREADQUEUE_H_
|
||||
#define _THREADQUEUE_H_ 1
|
||||
#ifndef UC_THREADQUEUE_H_
|
||||
#define UC_THREADQUEUE_H_
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
@@ -44,7 +44,7 @@ struct uc_threadmsg{
|
||||
/**
|
||||
* Callback function for the walk and destroy functions.
|
||||
*/
|
||||
typedef void (*uc_thread_queue_walk_func) (struct uc_threadmsg *msg);
|
||||
typedef void (*uc_thread_queue_walk_func) (struct uc_threadmsg *msg, void *cookie);
|
||||
|
||||
|
||||
/**
|
||||
@@ -240,23 +240,40 @@ long uc_thread_queue_length( struct uc_threadqueue *queue );
|
||||
* @param queue Pointer to the queue that should be cleaned
|
||||
* @param free_func pointer to function that will be called for each item.
|
||||
* The function must not in anyway interact with the queue.
|
||||
* @param cookie pointer passed back to the uc_thread_queue_walk_func
|
||||
* @return 0 on success EINVAL if queue is NULL EBUSY if someone is holding any locks on the queue
|
||||
*/
|
||||
int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func);
|
||||
int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func, void *cookie);
|
||||
|
||||
/**
|
||||
* Walk the elements of the queue, intended for debugging
|
||||
*
|
||||
* The supplied function will be called for each item in the queue, internal queue
|
||||
* locks are held while the function is called, so the supplied function must not
|
||||
* interact with the queue, else deadlock occors.
|
||||
* interact with the queue, else deadlock occurs.
|
||||
*
|
||||
* @param queue Pointer to the queue to walk
|
||||
* @param free_func pointer to function that will be called for each item.
|
||||
* @param cookie pointer passed back to the uc_thread_queue_walk_func
|
||||
* The function must not in anyway interact with the queue.
|
||||
* @return 0 on success
|
||||
*/
|
||||
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func);
|
||||
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func, void *cookie);
|
||||
|
||||
|
||||
/**
|
||||
* Clear the queue.
|
||||
* The free_func unless NULL, will be called for each element
|
||||
* locks are held while the function is called, so the supplied function must not
|
||||
* interact with the queue, else deadlock occurs.
|
||||
*
|
||||
* @param queue Pointer to the queue to clear
|
||||
* @param free_func pointer to function that will be called for each item, intended to e.g. release memory
|
||||
* @param cookie pointer passed back to the uc_thread_queue_walk_func
|
||||
* @return 0 on success
|
||||
*/
|
||||
int uc_thread_queue_clear(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func, void *cookie);
|
||||
|
||||
|
||||
/**
|
||||
* @}*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_TIMERS_H_
|
||||
#define UCORE_TIMERS_H_
|
||||
#ifndef UC_TIMERS_H_
|
||||
#define UC_TIMERS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
+34
-21
@@ -1,23 +1,16 @@
|
||||
#ifndef UCORE_UTILS_H_
|
||||
#define UCORE_UTILS_H_
|
||||
#ifndef UC_UTILS_H_
|
||||
#define UC_UTILS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "backtrace.h"
|
||||
|
||||
//Gnerate a compiler error if the compile time
|
||||
//constant expression fails
|
||||
#define UC_STATIC_ASSERT(expr) \
|
||||
do { \
|
||||
enum { assert_static__ = 1/(expr) }; \
|
||||
} while (0)
|
||||
enum { assert_static__ = 1/(expr) };
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TRACEF(fmt, ...)\
|
||||
do { \
|
||||
fprintf(stdout, "%s:%d (%s)\t" fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\
|
||||
fflush(stdout);\
|
||||
} while(0)
|
||||
#else
|
||||
#define TRACEF(fmt, ...)
|
||||
#endif
|
||||
|
||||
//MAX of a and b
|
||||
#define UC_MAX(a,b) \
|
||||
@@ -78,22 +71,42 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
||||
#define UC_STRINGIFY(x) UC_STRINGIFY_HLP(x)
|
||||
#define UC_STRINGIFY_HLP(x) #x
|
||||
|
||||
/** Macro that expands to a string for the current file:line
|
||||
*/
|
||||
#define UC_SRC_LOCATION __FILE__ ":" UC_STRINGIFY(__LINE__)
|
||||
/**
|
||||
* assert() that is not affected by NDEBUG define
|
||||
*/
|
||||
#define UC_ASSERT(expr) do {\
|
||||
if (!(expr) ) {\
|
||||
fprintf(stderr,\
|
||||
"UC_ASSERT failed '%s' %s:%d\n", UC_STRINGIFY(expr), __FILE__, __LINE__);\
|
||||
uc_backtrace_fd(3);\
|
||||
abort();\
|
||||
#define UC_ASSERT(expr)\
|
||||
do {\
|
||||
if (!(expr) ) {\
|
||||
fprintf(stderr,\
|
||||
"UC_ASSERT failed '%s' %s\n", UC_STRINGIFY(expr), UC_SRC_LOCATION);\
|
||||
uc_backtrace_fd(2);\
|
||||
abort();\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TRACEF(fmt, ...)\
|
||||
do { \
|
||||
fprintf(stdout, "%s (%s)\t" fmt, UC_SRC_LOCATION, __FUNCTION__, ##__VA_ARGS__);\
|
||||
fflush(stdout);\
|
||||
} while(0)
|
||||
#else
|
||||
#define TRACEF(fmt, ...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for asserting code that should not be reached,
|
||||
* terminates the program if executed
|
||||
*/
|
||||
#define UC_NOT_REACED() abort()
|
||||
#define UC_NOT_REACED()\
|
||||
do {\
|
||||
fprintf(stderr, "UC_NOT_REACED at %s\n", UC_SRC_LOCATION);\
|
||||
uc_backtrace_fd(2);\
|
||||
abort();\
|
||||
while (0)
|
||||
|
||||
/**
|
||||
* Round up X / y
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef UCORE_VERSION_H_
|
||||
#define UCORE_VERSION_H_
|
||||
#ifndef UC_VERSION_H_
|
||||
#define UC_VERSION_H_
|
||||
/**
|
||||
* @mainpage
|
||||
* @htmlonly
|
||||
|
||||
Reference in New Issue
Block a user