Merge branch 'dev' of ssh://box.fiane.intra/var/lib/git/libucore into dev
Conflicts: test/test_runner.c
This commit is contained in:
@@ -655,7 +655,7 @@ WARN_LOGFILE =
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = src
|
||||
INPUT = include
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||
|
||||
+14
@@ -36,6 +36,12 @@ AddOption('--test_xml',
|
||||
help='Create a result.xml when running the testsuite'
|
||||
)
|
||||
|
||||
AddOption('--coverage',
|
||||
dest='coverage',
|
||||
action='store_true',
|
||||
help='Build with coverage (gcov) support'
|
||||
)
|
||||
|
||||
AddOption('--stack-protection',
|
||||
dest = 'stack_protection',
|
||||
action='store_true',
|
||||
@@ -59,6 +65,11 @@ def InstallPerm(env, dest, files, perm):
|
||||
|
||||
|
||||
env = Environment(tools = ['default', 'textfile'])
|
||||
|
||||
#allow shell environment to override compiler
|
||||
if os.environ.has_key('CC'):
|
||||
env['CC'] = os.environ['CC']
|
||||
|
||||
env.AddMethod(InstallPerm)
|
||||
Export('env', 'build_type', 'prefix', 'version_info', 'test_xml')
|
||||
|
||||
@@ -80,6 +91,9 @@ if GetOption('stack_protection'):
|
||||
env.Append(CFLAGS = ['-fstack-protector', '--param=ssp-buffer-size=4'])
|
||||
env.Append(CPPDEFINES = ['_FORTIFY_SOURCE=2'])
|
||||
|
||||
if GetOption('coverage'):
|
||||
env.Append(CFLAGS = ['--coverage'])
|
||||
env.Append(LINKFLAGS = ['--coverage'])
|
||||
|
||||
#put all .sconsign files in one place
|
||||
env.SConsignFile()
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef UC_ATOMIC_H_
|
||||
#define UC_ATOMIC_H_
|
||||
|
||||
/** Atomic functions (macros). The ptr argument must be a pointer to
|
||||
* an integer type.
|
||||
* For gcc, see http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/_005f_005fsync-Builtins.html
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
/**
|
||||
* Atomically add val to *ptr
|
||||
* @return *ptr before the addition
|
||||
*/
|
||||
#define UC_ATOMIC_ADD(ptr, val) __sync_fetch_and_add((ptr), (val))
|
||||
|
||||
/**
|
||||
* Atomically subtract val from *ptr
|
||||
* @return *ptr before the subtraction
|
||||
*/
|
||||
#define UC_ATOMIC_SUB(ptr, val) __sync_fetch_and_add((ptr), -(val))
|
||||
|
||||
/**
|
||||
* Atomically decrement *ptr
|
||||
* @return *ptr before the decrement
|
||||
*/
|
||||
#define UC_ATOMIC_DEC(ptr) UC_ATOMIC_SUB((ptr), 1)
|
||||
|
||||
/**
|
||||
* Atomically increment *ptr
|
||||
* @return *ptr before the increment
|
||||
*/
|
||||
#define UC_ATOMIC_INC(ptr) UC_ATOMIC_SUB((ptr), 1)
|
||||
|
||||
|
||||
/**
|
||||
* Atomic Compare-And-Swap. If *ptr is oldval, write newwal to *ptr.
|
||||
* @return *ptr that was before the operation.
|
||||
*/
|
||||
#define UC_ATOMIC_CAS(ptr, oldval, newval) __sync_val_compare_and_swap((ptr), (oldval), (newval))
|
||||
|
||||
#else
|
||||
#error "No atomic operations implemented for this compiler"
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,12 @@
|
||||
#ifndef UC_BACKTRACE_H_
|
||||
#define UC_BACKTRACE_H_
|
||||
|
||||
#define UC_BACTRACE_STDERR uc_backtrace_fd(2)
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UC_BACTRACE_STDERR uc_backtrace_fd(2)
|
||||
/**
|
||||
* Print a stacktrace to the given file descriptor.
|
||||
*
|
||||
@@ -21,4 +24,8 @@ void uc_backtrace_fd(int fd);
|
||||
*/
|
||||
void uc_backtrace_buf(char *buf, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,7 +8,7 @@ extern "C" {
|
||||
struct UCBitVec {
|
||||
//storage for the bits
|
||||
unsigned long *vec;
|
||||
//length of the above vec. (Not the number of bits !)
|
||||
//length in bytes of the above vec.
|
||||
size_t vec_len;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An abstract clock.
|
||||
@@ -110,5 +113,9 @@ void uc_settable_clock_set_tv(struct UCoreSettableClock *uclock,
|
||||
void uc_settable_clock_set(struct UCoreSettableClock *uclock,
|
||||
time_t secs, suseconds_t usecs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+25
-5
@@ -3,6 +3,11 @@
|
||||
|
||||
#include "timers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define MUX_EV_READ (1U << 0x00)
|
||||
#define MUX_EV_WRITE (1U << 0x01)
|
||||
//#define MUX_EV_EXCEPT (1 << 0x02)
|
||||
@@ -38,6 +43,9 @@ struct IOMuxFD {
|
||||
};
|
||||
|
||||
/** Creates a new IOMux.
|
||||
*
|
||||
* @param type the underlying implementation to use @see IOMUX_TYPE
|
||||
* @return Newly allocated IOMux. NULL if memory allocation fails.
|
||||
*/
|
||||
struct IOMux *iomux_create(enum IOMUX_TYPE type);
|
||||
|
||||
@@ -53,19 +61,27 @@ struct IOMux *iomux_create_ex(enum IOMUX_TYPE type, struct UCoreClock *uclock);
|
||||
void iomux_delete(struct IOMux *mux);
|
||||
|
||||
/** Runs the event loop of the mux
|
||||
* returns if the number of file descriptors and timers are 0 or
|
||||
*
|
||||
* @return if the number of file descriptors and timers are 0 or
|
||||
* an error occurs */
|
||||
int iomux_run(struct IOMux *mux);
|
||||
|
||||
/* Adds a file descriptor to the watch set,
|
||||
* returns 0 on success, an errno value on error */
|
||||
/* Adds a file descriptor to the watch set.
|
||||
* The file descriptor integer value must reside in only
|
||||
* one struct IOMuxFD. Adding e.g. the same file descriptor
|
||||
* in 2 different struct IOMuxFD, one for read events and one for
|
||||
* write events is not supported.
|
||||
*
|
||||
* @return 0 on success, an errno value on error
|
||||
*/
|
||||
int iomux_register_fd(struct IOMux *mux, struct IOMuxFD *fd);
|
||||
|
||||
/** Removes the file descriptor*/
|
||||
int iomux_unregister_fd(struct IOMux *mux, struct IOMuxFD *fd);
|
||||
|
||||
/** Updates the events to watch for in fd->what
|
||||
* returns 0 on success, an errno value on error */
|
||||
* @return 0 on success, an errno value on error
|
||||
*/
|
||||
int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd);
|
||||
|
||||
|
||||
@@ -95,10 +111,14 @@ int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd);
|
||||
iomux_update_events((mux), (fd));\
|
||||
})
|
||||
|
||||
/** Returns a UCTimer instance tied to this mux.
|
||||
/** @return a UCTimer instance tied to this mux.
|
||||
* Used to schedule timers within this mux.
|
||||
*/
|
||||
struct UCTimers *iomux_get_timers(struct IOMux *mux);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -71,13 +71,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** The log levels defined by ucore logging*/
|
||||
/** The log levels defined by ucore logging
|
||||
* UC_LL_NONE must not be used in logging statements - but
|
||||
* can be used to suppress all logging for a destination or module*/
|
||||
enum UC_LOG_LEVEL {
|
||||
UC_LL_NONE = 0,
|
||||
UC_LL_DEBUG = 1,
|
||||
UC_LL_INFO = 3,
|
||||
UC_LL_WARNING = 5,
|
||||
UC_LL_ERROR = 7,
|
||||
UC_LL_NONE = 9,
|
||||
};
|
||||
|
||||
/** A destination for the logging messages*/
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef UC_MBUF_H_
|
||||
#define UC_MBUF_H_
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define UC_INLINE inline __attribute__((always_inline))
|
||||
#else
|
||||
# define UC_INLINE inline
|
||||
#endif
|
||||
|
||||
enum UC_MBUF_FLAGS {
|
||||
UC_MBUF_FL_MALLOC = 0x0001, //MBuf and MBuf->bufstart are seperatly malloc'd
|
||||
UC_MBUF_FL_MALLOC_BUF = 0x0001, //MBuf is not malloc'd. MBuf->bufstart is malloc'd
|
||||
UC_MBUF_FL_MALLOC_INLINE = 0x0002, //MBuf is one big malloc. Can't be resized
|
||||
UC_MBUF_FL_STATIC = 0x0004, //MBuf and MBuf->bustart is user controlled. Can't be resized
|
||||
};
|
||||
|
||||
struct MBuf {
|
||||
struct MBuf *next;
|
||||
uint8_t *p1;
|
||||
uint8_t *p2;
|
||||
uint8_t *p3;
|
||||
uint8_t *p4;
|
||||
void *cookie;
|
||||
uint32_t flags;
|
||||
uint32_t allocated;
|
||||
uint8_t *bufstart;
|
||||
uint8_t *head;
|
||||
uint8_t *tail;
|
||||
uint8_t inline_data[0];
|
||||
};
|
||||
|
||||
/* Conventions:
|
||||
* push - prepend data to the buffer (in the head room part)
|
||||
* pull - remove data from the beginning of the message.
|
||||
* put - Add data to the buffer.
|
||||
*/
|
||||
struct MBuf *uc_mbuf_new_hr(uint32_t len, uint32_t headroom);
|
||||
#define uc_mbuf_new(len) uc_mbuf_new_hr((len), 0)
|
||||
|
||||
struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom);
|
||||
#define uc_mbuf_new_inline(len) uc_mbuf_new_inline_hr((len), 0)
|
||||
|
||||
void uc_mbuf_free(struct MBuf *mbuf);
|
||||
struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf);
|
||||
|
||||
void uc_mbuf_init(struct MBuf *mbuf, uint8_t *buf, uint32_t len, uint32_t headroom, uint32_t flags);
|
||||
void uc_mbuf_zero(struct MBuf *mbuf);
|
||||
void uc_mbuf_reset(struct MBuf *mbuf);
|
||||
|
||||
static UC_INLINE uint32_t uc_mbuf_len(struct MBuf *mbuf)
|
||||
{
|
||||
return (uint32_t)(mbuf->tail - mbuf->head);
|
||||
}
|
||||
|
||||
static UC_INLINE uint32_t uc_mbuf_tailroom(struct MBuf *mbuf)
|
||||
{
|
||||
return mbuf->allocated - (uint32_t)(mbuf->tail - mbuf->bufstart);
|
||||
}
|
||||
|
||||
static inline uint32_t uc_mbuf_headroom(struct MBuf *mbuf)
|
||||
{
|
||||
return (uint32_t)(mbuf->head - mbuf->bufstart);
|
||||
}
|
||||
|
||||
uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size);
|
||||
|
||||
uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size);
|
||||
|
||||
uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size);
|
||||
|
||||
#undef UC_INLINE
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef UCORE_MERSENNE_TWISTER_H
|
||||
#define UCORE_MERSENNE_TWISTER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Context used for the PRNG*/
|
||||
#define MT_RAND_N 624
|
||||
@@ -23,5 +26,9 @@ void mtsrand(int seed, MTRand *r);
|
||||
*/
|
||||
unsigned int mtrand(MTRand *r);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Read the content of a file.
|
||||
* The returned char* is malloced memory and must be freed by the caller.
|
||||
* The content is terminated by a nul byte, regardless of whether the content
|
||||
@@ -17,4 +21,8 @@
|
||||
char *
|
||||
uc_read_file(const char *file_name, size_t *length, size_t max);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#include <sys/time.h>
|
||||
#include "rbtree.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct UCTimer;
|
||||
struct UCTimers;
|
||||
@@ -140,4 +143,8 @@ int uc_timers_run(struct UCTimers *timers);
|
||||
|
||||
//uc_timers_destroy(struct UCTimers *timers) is currently missing..
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,12 +48,14 @@
|
||||
//struct foo *f = CONTAINER_OF(p, struct foo, zap);
|
||||
#define CONTAINER_OF(ptr, type, member) ({ \
|
||||
typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (unsigned char *)__mptr - offsetof(type, member) ); })
|
||||
(type *)((void *)(unsigned char *)__mptr - offsetof(type, member) ); })
|
||||
|
||||
//the void* cast is to suppress alignment warnings
|
||||
|
||||
//Same as CONTAINER_OF, but for a const pointer to avoid gcc warnings..
|
||||
#define CONST_CONTAINER_OF(ptr, type, member) ({ \
|
||||
const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
||||
(const type *)( (const unsigned char *)__mptr - offsetof(const type, member) ); })
|
||||
(const type *)((const void *)(const unsigned char *)__mptr - offsetof(const type, member) ); })
|
||||
|
||||
/** Align a value.
|
||||
* @param val value to align
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
* </pre>
|
||||
* @endhtmlonly
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Major version of the ucore library*/
|
||||
extern const int ucore_version_major;
|
||||
@@ -46,5 +49,10 @@ extern const char ucore_version_str[];
|
||||
/** Hostname where the library was built
|
||||
*/
|
||||
extern const char ucore_build_host[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ void uc_backtrace_buf(char *buf, size_t len)
|
||||
buf[0] = 0;
|
||||
|
||||
lines = backtrace_symbols(buffer, ptrs);
|
||||
if (lines != NULL) {
|
||||
for (i = 1; i < ptrs; i++) {
|
||||
|
||||
int rc = snprintf(buf, remaining, "%s\n", lines[i]);
|
||||
@@ -46,6 +47,7 @@ void uc_backtrace_buf(char *buf, size_t len)
|
||||
remaining -= rc;
|
||||
buf += rc;
|
||||
}
|
||||
}
|
||||
|
||||
free(lines);
|
||||
}
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "ucore/iomux_impl.h"
|
||||
#include "iomux_impl.h"
|
||||
|
||||
//epoll (linux specific) IO mux.
|
||||
//We stuff the struct IOMuxFD pointer in the event.data.ptr slot
|
||||
@@ -183,7 +183,7 @@ again:
|
||||
fd->callback(mux_, fd, events);
|
||||
//be sure not to use fd after the callback, it might been removed.
|
||||
|
||||
mux->pending_events[i].data.ptr = NULL;
|
||||
mux->pending_events[i].data.ptr = NULL; //clear from pending list
|
||||
|
||||
event_cnt++;
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,8 +2,8 @@
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ucore/iomux_impl.h>
|
||||
#include "ucore/clock.h"
|
||||
#include "iomux_impl.h"
|
||||
|
||||
|
||||
//dispatchers for the IOMux implementations */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef IO_MUX_IMPL_H_
|
||||
#define IO_MUX_IMPL_H_
|
||||
|
||||
#include "iomux.h"
|
||||
#include "timers.h"
|
||||
#include "ucore/iomux.h"
|
||||
#include "ucore/timers.h"
|
||||
/** struct for IOMux implementations */
|
||||
struct IOMux {
|
||||
|
||||
+3
-2
@@ -5,8 +5,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include "ucore/iomux_impl.h"
|
||||
#include "ucore/utils.h"
|
||||
#include "iomux_impl.h"
|
||||
|
||||
#define IOMUX_GROW_CHUNK (32)
|
||||
|
||||
@@ -168,17 +168,18 @@ again:
|
||||
}
|
||||
|
||||
if (FD_ISSET(mux->descriptors[i]->fd, &read_set)) {
|
||||
rc--;
|
||||
events |= MUX_EV_READ;
|
||||
}
|
||||
|
||||
if (FD_ISSET(mux->descriptors[i]->fd, &write_set)) {
|
||||
rc--;
|
||||
events |= MUX_EV_WRITE;
|
||||
}
|
||||
|
||||
if (events) {
|
||||
assert(mux->descriptors[i]->callback != NULL);
|
||||
mux->descriptors[i]->callback(mux_, mux->descriptors[i], events);
|
||||
rc--;
|
||||
event_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-16
@@ -68,17 +68,18 @@ static SLIST_HEAD(, uc_log_destination) g_destinations;
|
||||
static int uc_log_reopen_file(struct uc_log_destination *dest);
|
||||
//Uses enum UC_LOG_LEVEL as index
|
||||
static const char *const g_log_levels[] = {
|
||||
"NONE",
|
||||
"UNKNOWN_0",
|
||||
"DEBUG",
|
||||
"UNKNOWN_2",
|
||||
"INFO",
|
||||
"UNKNOWN_4",
|
||||
"WARNING",
|
||||
"UNKNOWN_6",
|
||||
"ERROR"
|
||||
"ERROR",
|
||||
"NONE"
|
||||
};
|
||||
|
||||
inline const char *uc_ll_2_str(enum UC_LOG_LEVEL l)
|
||||
const char *uc_ll_2_str(enum UC_LOG_LEVEL l)
|
||||
{
|
||||
if (l < ARRAY_SIZE(g_log_levels)) {
|
||||
return g_log_levels[l];
|
||||
@@ -104,7 +105,6 @@ static int uc_str_2_ll(const char *str, size_t len)
|
||||
static inline int uc_ll_2_syslog(enum UC_LOG_LEVEL l)
|
||||
{
|
||||
switch(l) {
|
||||
case UC_LL_NONE:
|
||||
case UC_LL_DEBUG:
|
||||
return LOG_DEBUG;
|
||||
case UC_LL_INFO:
|
||||
@@ -113,6 +113,9 @@ static inline int uc_ll_2_syslog(enum UC_LOG_LEVEL l)
|
||||
return LOG_WARNING;
|
||||
case UC_LL_ERROR:
|
||||
return LOG_ERR;
|
||||
case UC_LL_NONE:
|
||||
return LOG_CRIT; //Fishy, but this should never happen
|
||||
|
||||
}
|
||||
|
||||
return LOG_INFO;
|
||||
@@ -544,22 +547,14 @@ void uc_logf(int log_level, int module, int raw,
|
||||
{
|
||||
va_list ap;
|
||||
struct uc_log_destination *dest;
|
||||
const struct uc_log_module *log_module;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
pthread_mutex_lock(&g_log_lock);
|
||||
|
||||
//Find the module doign the logging, or use the unknown module -
|
||||
//the latter would indicate a bug somewhere in the application as it should
|
||||
//always specify a known module
|
||||
if (module >= 0 && module < g_modules.cnt)
|
||||
log_module = &g_modules.mods[module];
|
||||
else
|
||||
log_module = &g_unknown_module;
|
||||
|
||||
//do logging for each destination
|
||||
SLIST_FOREACH(dest, &g_destinations, entry) {
|
||||
const struct uc_log_module *log_module;
|
||||
va_list apc;
|
||||
int module_log_level;
|
||||
|
||||
@@ -568,11 +563,16 @@ void uc_logf(int log_level, int module, int raw,
|
||||
if (log_level < dest->log_level)
|
||||
continue;
|
||||
|
||||
//individual module level
|
||||
if (module >= 0 && module < g_modules.cnt)
|
||||
//Find the module doing the logging, or use the unknown module -
|
||||
//the latter would indicate a bug somewhere in the application as it should
|
||||
//always specify a known module
|
||||
if (module >= 0 && module < g_modules.cnt) {
|
||||
module_log_level = dest->module_settings[module].log_level;
|
||||
else //application bug. use global/unknown module
|
||||
log_module = &g_modules.mods[module];
|
||||
} else {
|
||||
log_module = &g_unknown_module;
|
||||
module_log_level = log_module->log_level;
|
||||
}
|
||||
|
||||
if (log_level < module_log_level)
|
||||
continue;
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "ucore/mbuf.h"
|
||||
|
||||
uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size)
|
||||
{
|
||||
uint8_t *data = mbuf->tail;
|
||||
|
||||
if (uc_mbuf_tailroom(mbuf) < size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbuf->tail += size;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size)
|
||||
{
|
||||
if (uc_mbuf_headroom(mbuf) < size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbuf->head -= size;
|
||||
|
||||
return mbuf->head;
|
||||
}
|
||||
|
||||
uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size)
|
||||
{
|
||||
uint8_t *data = mbuf->head;
|
||||
|
||||
if (uc_mbuf_len(mbuf) < size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbuf->head += size;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void uc_mbuf_init(struct MBuf *mbuf, uint8_t *buf, uint32_t len, uint32_t headroom, uint32_t flags)
|
||||
{
|
||||
mbuf->bufstart = buf;
|
||||
mbuf->next = NULL;
|
||||
mbuf->p1 = mbuf->p2 = mbuf->p3 = mbuf->p4 = NULL;
|
||||
mbuf->cookie = NULL;
|
||||
mbuf->flags = flags;
|
||||
mbuf->allocated = len + headroom;
|
||||
mbuf->head = mbuf->bufstart + headroom;
|
||||
mbuf->tail = mbuf->head;
|
||||
}
|
||||
|
||||
struct MBuf *uc_mbuf_new_hr(uint32_t len, uint32_t headroom)
|
||||
{
|
||||
struct MBuf *mbuf;
|
||||
uint8_t *buf;
|
||||
|
||||
mbuf = malloc(sizeof *mbuf);
|
||||
if (mbuf == NULL)
|
||||
return mbuf;
|
||||
|
||||
buf = malloc(len + headroom);
|
||||
if (buf == NULL) {
|
||||
free(mbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uc_mbuf_init(mbuf, buf, len, headroom, UC_MBUF_FL_MALLOC);
|
||||
|
||||
return mbuf;
|
||||
}
|
||||
|
||||
struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom)
|
||||
{
|
||||
struct MBuf *mbuf;
|
||||
|
||||
mbuf = malloc(sizeof *mbuf + len + headroom);
|
||||
if (mbuf == NULL)
|
||||
return mbuf;
|
||||
|
||||
uc_mbuf_init(mbuf, mbuf->inline_data, len, headroom, UC_MBUF_FL_MALLOC_INLINE);
|
||||
|
||||
return mbuf;
|
||||
}
|
||||
|
||||
void uc_mbuf_free(struct MBuf *mbuf)
|
||||
{
|
||||
if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_BUF))
|
||||
free(mbuf->bufstart);
|
||||
|
||||
if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_INLINE))
|
||||
free(mbuf);
|
||||
}
|
||||
|
||||
void uc_mbuf_zero(struct MBuf *mbuf)
|
||||
{
|
||||
memset(mbuf->bufstart, 0, mbuf->allocated);
|
||||
}
|
||||
|
||||
struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf)
|
||||
{
|
||||
uint32_t len;
|
||||
struct MBuf *copy;
|
||||
uint8_t *data;
|
||||
|
||||
len = uc_mbuf_len(mbuf);
|
||||
|
||||
copy = uc_mbuf_new_hr(len, uc_mbuf_headroom(mbuf));
|
||||
if (copy == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = uc_mbuf_put(copy, len);
|
||||
memcpy(data, mbuf->head, len);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
#undef UC_INLINE
|
||||
|
||||
+9
-5
@@ -6,8 +6,10 @@ uc_tvadd(struct timeval *dst, const struct timeval *a, const struct timeval *b)
|
||||
dst->tv_sec = a->tv_sec + b->tv_sec;
|
||||
dst->tv_usec = a->tv_usec + b->tv_usec;
|
||||
|
||||
if (dst->tv_usec >= 1000000)
|
||||
dst->tv_sec++, dst->tv_usec -= 1000000;
|
||||
if (dst->tv_usec >= 1000000) {
|
||||
dst->tv_sec++;
|
||||
dst->tv_usec -= 1000000;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
@@ -18,8 +20,10 @@ uc_tvsub(struct timeval *dst, const struct timeval *a, const struct timeval *b)
|
||||
dst->tv_sec = a->tv_sec - b->tv_sec;
|
||||
dst->tv_usec = a->tv_usec - b->tv_usec;
|
||||
|
||||
if (dst->tv_usec < 0)
|
||||
dst->tv_sec--, dst->tv_usec += 1000000;
|
||||
if (dst->tv_usec < 0) {
|
||||
dst->tv_sec--;
|
||||
dst->tv_usec += 1000000;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
@@ -41,7 +45,7 @@ uc_tvcmp(const struct timeval *a, const struct timeval *b)
|
||||
}
|
||||
|
||||
struct timeval *
|
||||
uc_to2tv(struct timeval *dst, unsigned long ms)
|
||||
uc_ms2tv(struct timeval *dst, unsigned long long ms)
|
||||
{
|
||||
dst->tv_sec = ms / 1000;
|
||||
dst->tv_usec = ms % 1000 * 1000;
|
||||
|
||||
@@ -410,6 +410,64 @@ START_TEST (test_logfile_dest_mask)
|
||||
fail_if(st.st_size != 14*2, "was %ld\n", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_loglevel_module_none)
|
||||
|
||||
struct uc_log_module m = {
|
||||
.id = 0,
|
||||
.short_name = "MOD1",
|
||||
.long_name = "Module 1",
|
||||
.log_level = UC_LL_NONE,
|
||||
};
|
||||
struct uc_log_modules mods = {
|
||||
.mods = &m,
|
||||
.cnt = 1,
|
||||
};
|
||||
struct stat st;
|
||||
struct uc_log_destination *dest;
|
||||
int rc;
|
||||
|
||||
uc_log_init(&mods);
|
||||
|
||||
dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1);
|
||||
fail_if(dest == NULL);
|
||||
uc_log_add_destination(dest);
|
||||
|
||||
UC_LOGFR(UC_LL_ERROR, 0, "Lorum ipson %d\n", 1);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_loglevel_dest_none)
|
||||
|
||||
struct uc_log_module m = {
|
||||
.id = 0,
|
||||
.short_name = "MOD1",
|
||||
.long_name = "Module 1",
|
||||
.log_level = UC_LL_DEBUG,
|
||||
};
|
||||
struct uc_log_modules mods = {
|
||||
.mods = &m,
|
||||
.cnt = 1,
|
||||
};
|
||||
struct stat st;
|
||||
struct uc_log_destination *dest;
|
||||
int rc;
|
||||
|
||||
uc_log_init(&mods);
|
||||
|
||||
dest = uc_log_new_file(FILE_NAME, UC_LL_NONE, 1);
|
||||
fail_if(dest == NULL);
|
||||
uc_log_add_destination(dest);
|
||||
|
||||
UC_LOGFR(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *logging_suite(void)
|
||||
{
|
||||
@@ -435,6 +493,9 @@ Suite *logging_suite(void)
|
||||
tcase_add_test(tc2, test_logfile_invalid_file_after_reopen);
|
||||
tcase_add_test(tc1, test_logfile_raw);
|
||||
|
||||
tcase_add_test(tc1, test_loglevel_module_none);
|
||||
tcase_add_test(tc1, test_loglevel_dest_none);
|
||||
|
||||
|
||||
tcase_add_checked_fixture(tc1, logging_rm_files, logging_rm_files);
|
||||
tcase_add_checked_fixture(tc2, logging_setup_subdir, logging_rm_subdir);
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
#include <check.h>
|
||||
#include <string.h>
|
||||
#include <ucore/mbuf.h>
|
||||
|
||||
|
||||
START_TEST (test_mbuf_new)
|
||||
struct MBuf *mbuf;
|
||||
|
||||
mbuf = uc_mbuf_new(110);
|
||||
|
||||
fail_if(mbuf == NULL);
|
||||
fail_if(uc_mbuf_len(mbuf) != 0);
|
||||
fail_if(uc_mbuf_headroom(mbuf) != 0);
|
||||
fail_if(uc_mbuf_tailroom(mbuf) != 110);
|
||||
fail_if(mbuf->next != NULL);
|
||||
fail_if(mbuf->p1 != NULL);
|
||||
fail_if(mbuf->p2 != NULL);
|
||||
fail_if(mbuf->p3 != NULL);
|
||||
fail_if(mbuf->p4 != NULL);
|
||||
fail_if(mbuf->cookie != NULL);
|
||||
fail_if(mbuf->head != mbuf->tail);
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_mbuf_new_inline)
|
||||
struct MBuf *mbuf;
|
||||
|
||||
mbuf = uc_mbuf_new_inline(110);
|
||||
|
||||
fail_if(mbuf == NULL);
|
||||
fail_if(uc_mbuf_len(mbuf) != 0);
|
||||
fail_if(uc_mbuf_headroom(mbuf) != 0);
|
||||
fail_if(uc_mbuf_tailroom(mbuf) != 110);
|
||||
fail_if(mbuf->next != NULL);
|
||||
fail_if(mbuf->p1 != NULL);
|
||||
fail_if(mbuf->p2 != NULL);
|
||||
fail_if(mbuf->p3 != NULL);
|
||||
fail_if(mbuf->p4 != NULL);
|
||||
fail_if(mbuf->cookie != NULL);
|
||||
fail_if(mbuf->head != mbuf->tail);
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_mbuf_new_headroom)
|
||||
struct MBuf *mbuf;
|
||||
|
||||
mbuf = uc_mbuf_new_hr(110,20);
|
||||
|
||||
fail_if(mbuf == NULL);
|
||||
fail_if(uc_mbuf_len(mbuf) != 0);
|
||||
fail_if(uc_mbuf_headroom(mbuf) != 20);
|
||||
fail_if(uc_mbuf_tailroom(mbuf) != 110);
|
||||
fail_if(mbuf->next != NULL);
|
||||
fail_if(mbuf->p1 != NULL);
|
||||
fail_if(mbuf->p2 != NULL);
|
||||
fail_if(mbuf->p3 != NULL);
|
||||
fail_if(mbuf->p4 != NULL);
|
||||
fail_if(mbuf->cookie != NULL);
|
||||
fail_if(mbuf->head != mbuf->tail);
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_mbuf_put)
|
||||
struct MBuf *mbuf;
|
||||
uint8_t *data;
|
||||
|
||||
mbuf = uc_mbuf_new_inline(111);
|
||||
fail_if(mbuf == NULL);
|
||||
|
||||
data = uc_mbuf_put(mbuf, 111);
|
||||
fail_if(data == NULL);
|
||||
fail_if(uc_mbuf_len(mbuf) != 111);
|
||||
fail_if(uc_mbuf_tailroom(mbuf) != 0);
|
||||
|
||||
memset(data, 0, 111);
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_mbuf_put_fail)
|
||||
struct MBuf *mbuf;
|
||||
uint8_t *data;
|
||||
|
||||
mbuf = uc_mbuf_new_inline(10);
|
||||
fail_if(mbuf == NULL);
|
||||
|
||||
data = uc_mbuf_put(mbuf, 11);
|
||||
fail_if(data != NULL);
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_mbuf_push)
|
||||
struct MBuf *mbuf;
|
||||
uint8_t *data;
|
||||
|
||||
mbuf = uc_mbuf_new_hr(10,1);
|
||||
fail_if(mbuf == NULL);
|
||||
|
||||
data = uc_mbuf_push(mbuf, 1);
|
||||
fail_if(data == NULL);
|
||||
fail_if(uc_mbuf_len(mbuf) != 1);
|
||||
fail_if(uc_mbuf_headroom(mbuf) != 0);
|
||||
|
||||
*data = 0;
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST (test_mbuf_push_fail)
|
||||
struct MBuf *mbuf;
|
||||
uint8_t *data;
|
||||
|
||||
mbuf = uc_mbuf_new_hr(1,2);
|
||||
fail_if(mbuf == NULL);
|
||||
|
||||
data = uc_mbuf_push(mbuf, 3);
|
||||
fail_if(data != NULL);
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_mbuf_pull)
|
||||
struct MBuf *mbuf;
|
||||
uint8_t *data1;
|
||||
uint8_t *data2;
|
||||
|
||||
mbuf = uc_mbuf_new_inline(10);
|
||||
fail_if(mbuf == NULL);
|
||||
|
||||
data1 = uc_mbuf_put(mbuf, 10);
|
||||
fail_if(data1 == NULL);
|
||||
fail_if(uc_mbuf_tailroom(mbuf) != 0);
|
||||
fail_if(uc_mbuf_len(mbuf) != 10);
|
||||
|
||||
data2 = uc_mbuf_pull(mbuf,10);
|
||||
fail_if(data2 == NULL);
|
||||
fail_if(data1 != data2);
|
||||
fail_if(uc_mbuf_len(mbuf) != 0);
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_mbuf_pull_fail)
|
||||
struct MBuf *mbuf;
|
||||
uint8_t *data1;
|
||||
uint8_t *data2;
|
||||
|
||||
mbuf = uc_mbuf_new_inline(10);
|
||||
fail_if(mbuf == NULL);
|
||||
|
||||
data1 = uc_mbuf_put(mbuf, 10);
|
||||
fail_if(data1 == NULL);
|
||||
fail_if(uc_mbuf_len(mbuf) != 10);
|
||||
|
||||
data2 = uc_mbuf_pull(mbuf,11);
|
||||
fail_if(data2 != NULL);
|
||||
fail_if(uc_mbuf_len(mbuf) != 10);
|
||||
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_mbuf_copy)
|
||||
struct MBuf *mbuf;
|
||||
uint8_t *data1;
|
||||
struct MBuf *copy;
|
||||
|
||||
mbuf = uc_mbuf_new_inline_hr(10,5);
|
||||
fail_if(mbuf == NULL);
|
||||
|
||||
data1 = uc_mbuf_put(mbuf, 10);
|
||||
fail_if(data1 == NULL);
|
||||
|
||||
strcpy((char*)data1, "123456789");
|
||||
|
||||
copy = uc_mbuf_copy_data(mbuf);
|
||||
fail_if(copy == NULL);
|
||||
fail_if(uc_mbuf_len(copy) != 10);
|
||||
fail_if(uc_mbuf_headroom(copy) != 5);
|
||||
fail_if(memcmp(mbuf->head, copy->head, 10) != 0);
|
||||
|
||||
uc_mbuf_free(mbuf);
|
||||
uc_mbuf_free(copy);
|
||||
|
||||
END_TEST
|
||||
|
||||
|
||||
|
||||
Suite *mbuf_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("mbuf");
|
||||
TCase *tc = tcase_create("mbuf tests");
|
||||
tcase_add_test(tc, test_mbuf_new);
|
||||
tcase_add_test(tc, test_mbuf_new_inline);
|
||||
tcase_add_test(tc, test_mbuf_new_headroom);
|
||||
tcase_add_test(tc, test_mbuf_put);
|
||||
tcase_add_test(tc, test_mbuf_put_fail);
|
||||
tcase_add_test(tc, test_mbuf_push);
|
||||
tcase_add_test(tc, test_mbuf_push_fail);
|
||||
tcase_add_test(tc, test_mbuf_pull);
|
||||
tcase_add_test(tc, test_mbuf_pull_fail);
|
||||
tcase_add_test(tc, test_mbuf_copy);
|
||||
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,65 @@ START_TEST (test_read_file_boundary)
|
||||
free(content);
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_read_file_devnull)
|
||||
char *content;
|
||||
size_t len = 123;
|
||||
|
||||
content = uc_read_file("/dev/null", &len, 1024);
|
||||
fail_if(content == NULL);
|
||||
fail_if(len != 0);
|
||||
free(content);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_read_file_too_big)
|
||||
char *content;
|
||||
const char *filename = "test_read_file_too_big";
|
||||
size_t len;
|
||||
ssize_t rc;
|
||||
|
||||
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
|
||||
fail_if(fd == -1);
|
||||
|
||||
rc = write(fd, "hello", 5);
|
||||
fail_if(rc != 5, "rc was %ld", (long)rc);
|
||||
|
||||
close(fd);
|
||||
|
||||
content = uc_read_file(filename, &len, 4);
|
||||
|
||||
fail_if(errno != EMSGSIZE);
|
||||
fail_if(content != NULL);
|
||||
|
||||
unlink(filename);
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_read_file_big)
|
||||
char *content;
|
||||
const char *filename = "test_read_file_big";
|
||||
char buf[4096 * 16];
|
||||
size_t len;
|
||||
ssize_t rc;
|
||||
|
||||
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
|
||||
fail_if(fd == -1);
|
||||
memset(buf, 'a', sizeof buf);
|
||||
|
||||
rc = write(fd, buf, sizeof buf);
|
||||
fail_if(rc != sizeof buf, "rc was %ld", (long)rc);
|
||||
|
||||
close(fd);
|
||||
|
||||
content = uc_read_file(filename, &len, 4096*16);
|
||||
fail_if(content == NULL);
|
||||
fail_if(len != sizeof buf);
|
||||
fail_if(memcmp(content, buf, sizeof buf) != 0);
|
||||
|
||||
free(content);
|
||||
|
||||
unlink(filename);
|
||||
END_TEST
|
||||
|
||||
Suite *read_file_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("read_file");
|
||||
@@ -99,6 +158,10 @@ Suite *read_file_suite(void)
|
||||
tcase_add_test(tc, test_read_file_simple);
|
||||
tcase_add_test(tc, test_read_file_greater_than_max);
|
||||
tcase_add_test(tc, test_read_file_boundary);
|
||||
tcase_add_test(tc, test_read_file_devnull);
|
||||
tcase_add_test(tc, test_read_file_too_big);
|
||||
tcase_add_test(tc, test_read_file_big);
|
||||
|
||||
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ extern Suite *clock_suite(void);
|
||||
extern Suite *seq_suite(void);
|
||||
extern Suite *sat_math_suite(void);
|
||||
extern Suite *timers_suite(void);
|
||||
extern Suite *mbuf_suite(void);
|
||||
extern Suite *human_bytesz_suite(void);
|
||||
|
||||
static suite_func suites[] = {
|
||||
@@ -35,6 +36,7 @@ static suite_func suites[] = {
|
||||
seq_suite,
|
||||
sat_math_suite,
|
||||
timers_suite,
|
||||
mbuf_suite,
|
||||
human_bytesz_suite
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user