From d0b65a9f58d4ce14a0f3ff211b56795f8c766fc3 Mon Sep 17 00:00:00 2001
From: Christopher Rienzo <chris@rienzo.net>
Date: Fri, 6 Apr 2012 14:38:30 +0000
Subject: [PATCH] Add test driver for mod_posix_timer

---
 src/mod/timers/mod_posix_timer/test/Makefile |   6 +
 src/mod/timers/mod_posix_timer/test/README   |   2 +
 src/mod/timers/mod_posix_timer/test/main.c   |  44 +++++++
 src/mod/timers/mod_posix_timer/test/switch.c |  69 +++++++++++
 src/mod/timers/mod_posix_timer/test/switch.h | 122 +++++++++++++++++++
 5 files changed, 243 insertions(+)
 create mode 100644 src/mod/timers/mod_posix_timer/test/Makefile
 create mode 100644 src/mod/timers/mod_posix_timer/test/README
 create mode 100644 src/mod/timers/mod_posix_timer/test/main.c
 create mode 100644 src/mod/timers/mod_posix_timer/test/switch.c
 create mode 100644 src/mod/timers/mod_posix_timer/test/switch.h

diff --git a/src/mod/timers/mod_posix_timer/test/Makefile b/src/mod/timers/mod_posix_timer/test/Makefile
new file mode 100644
index 0000000000..856345298b
--- /dev/null
+++ b/src/mod/timers/mod_posix_timer/test/Makefile
@@ -0,0 +1,6 @@
+all:
+	gcc ../mod_posix_timer.c main.c switch.c -I. -o timer_test -lpthread -lrt -g -DLOG_LEVEL=-1
+
+clean:
+	-rm timer_test
+
diff --git a/src/mod/timers/mod_posix_timer/test/README b/src/mod/timers/mod_posix_timer/test/README
new file mode 100644
index 0000000000..f47c511272
--- /dev/null
+++ b/src/mod/timers/mod_posix_timer/test/README
@@ -0,0 +1,2 @@
+Stress test for mod_posix_timer.  Runs without FreeSWITCH.
+
diff --git a/src/mod/timers/mod_posix_timer/test/main.c b/src/mod/timers/mod_posix_timer/test/main.c
new file mode 100644
index 0000000000..1df054566d
--- /dev/null
+++ b/src/mod/timers/mod_posix_timer/test/main.c
@@ -0,0 +1,44 @@
+
+#include <switch.h>
+#include <stdlib.h>
+
+extern SWITCH_MODULE_LOAD_FUNCTION(mod_posix_timer_load);
+extern SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_posix_timer_shutdown);
+
+switch_loadable_module_interface_t *mod = NULL;
+switch_memory_pool_t pool = { 0 };
+
+int main (int argc, char **argv)
+{
+	int i;
+	switch_timer_interface_t *timer_if;
+	switch_timer_t *timer[1000];
+
+	mod_posix_timer_load(&mod, &pool);
+	timer_if = mod->timer;
+
+
+	// TODO create multi-threaded test
+
+	// create 10 ms timers
+	for (i = 0; i < 1000; i++) {
+		timer[i] = malloc(sizeof(switch_timer_t));
+		memset(timer[i], 0, sizeof(switch_timer_t));
+		timer[i]->interval = 1;
+		timer[i]->samples = 8;
+		timer_if->timer_init(timer[i]);
+	}
+
+	for (i = 0; i < 50000; i++) {
+		timer_if->timer_next(timer[0]);
+	}
+
+	// destroy timers
+	for (i = 0; i < 1000; i++) {
+		timer_if->timer_destroy(timer[i]);
+		free(timer[i]);
+	}
+
+	mod_posix_timer_shutdown();
+	return 0;
+}
diff --git a/src/mod/timers/mod_posix_timer/test/switch.c b/src/mod/timers/mod_posix_timer/test/switch.c
new file mode 100644
index 0000000000..7ac7a3a97c
--- /dev/null
+++ b/src/mod/timers/mod_posix_timer/test/switch.c
@@ -0,0 +1,69 @@
+#include <switch.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+
+switch_loadable_module_interface_t * switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name)
+{
+	return malloc(sizeof(switch_loadable_module_interface_t));
+}
+
+void * switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, int iname)
+{
+	mod->timer = malloc(sizeof(switch_timer_interface_t));
+	return mod->timer;
+}
+
+switch_status_t switch_mutex_lock(switch_mutex_t *mutex)
+{
+	return pthread_mutex_lock(mutex);
+}
+
+switch_status_t switch_mutex_unlock(switch_mutex_t *mutex)
+{
+	return pthread_mutex_unlock(mutex);
+}
+
+switch_status_t switch_mutex_init(switch_mutex_t **mutex, int flags, switch_memory_pool_t *pool)
+{
+	pthread_mutexattr_t atts = { 0 };
+	pthread_mutexattr_init(&atts);
+	if (flags == SWITCH_MUTEX_NESTED) {
+		pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE_NP);
+	}
+	*mutex = malloc(sizeof(switch_mutex_t));
+	return pthread_mutex_init(*mutex, &atts);
+}
+
+switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
+{
+	*cond = malloc(sizeof(switch_thread_cond_t));
+	return pthread_cond_init(*cond, NULL);
+}
+
+switch_status_t switch_thread_cond_timedwait(switch_thread_cond_t *cond, switch_mutex_t *mutex, int wait)
+{
+	struct timespec dur = { 0, 0 };
+	clock_gettime(CLOCK_REALTIME, &dur);
+	dur.tv_sec = wait / 1000000000;
+	dur.tv_nsec = wait % 1000000000; 
+	return pthread_cond_timedwait(cond, mutex, &dur);
+}
+
+switch_status_t switch_thread_cond_broadcast(switch_thread_cond_t *cond)
+{
+	return pthread_cond_broadcast(cond);
+}
+
+void switch_log_printf(int dummy, int level, char *format, ...)
+{
+	va_list vl;
+	va_start(vl, format);
+	if (level > LOG_LEVEL) {
+		vprintf(format, vl);
+	}
+	va_end(vl);
+}
+
+
diff --git a/src/mod/timers/mod_posix_timer/test/switch.h b/src/mod/timers/mod_posix_timer/test/switch.h
new file mode 100644
index 0000000000..25391943fb
--- /dev/null
+++ b/src/mod/timers/mod_posix_timer/test/switch.h
@@ -0,0 +1,122 @@
+#ifndef SWITCH_H
+#define SWITCH_H 
+
+#include <pthread.h>
+#include <time.h>
+#include <signal.h>
+#include <string.h>
+
+#define SWITCH_STATUS_SUCCESS 0
+#define SWITCH_STATUS_GENERR 1
+#define SWITCH_STATUS_FALSE 2
+
+#define SWITCH_MUTEX_NESTED 1
+
+#define SWITCH_CHANNEL_LOG 0
+
+#define SWITCH_LOG_INFO 0
+
+typedef int switch_status_t;
+typedef size_t switch_size_t;
+typedef pthread_mutex_t switch_mutex_t;
+typedef pthread_cond_t switch_thread_cond_t;
+typedef int switch_memory_pool_t;
+typedef int switch_bool_t;
+
+#define SWITCH_TIMER_INTERFACE 0
+
+typedef struct switch_loadable_module_interface switch_loadable_module_interface_t;
+typedef struct switch_timer_interface switch_timer_interface_t;
+
+typedef int switch_module_flag_t;
+#define SWITCH_API_VERSION 0
+#define SWITCH_MOD_DECLARE_DATA
+#define SMODF_NONE 0
+#define SWITCH_MODULE_LOAD_ARGS (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool)
+#define SWITCH_MODULE_RUNTIME_ARGS (void)
+#define SWITCH_MODULE_SHUTDOWN_ARGS (void)
+typedef switch_status_t (*switch_module_load_t) SWITCH_MODULE_LOAD_ARGS;
+typedef switch_status_t (*switch_module_runtime_t) SWITCH_MODULE_RUNTIME_ARGS;
+typedef switch_status_t (*switch_module_shutdown_t) SWITCH_MODULE_SHUTDOWN_ARGS;
+#define SWITCH_MODULE_LOAD_FUNCTION(name) switch_status_t name SWITCH_MODULE_LOAD_ARGS
+#define SWITCH_MODULE_RUNTIME_FUNCTION(name) switch_status_t name SWITCH_MODULE_RUNTIME_ARGS
+#define SWITCH_MODULE_SHUTDOWN_FUNCTION(name) switch_status_t name SWITCH_MODULE_SHUTDOWN_ARGS
+typedef struct switch_loadable_module_function_table {
+    int switch_api_version;
+    switch_module_load_t load;
+    switch_module_shutdown_t shutdown;
+    switch_module_runtime_t runtime;
+    switch_module_flag_t flags;
+} switch_loadable_module_function_table_t;
+
+#define SWITCH_MODULE_DEFINITION_EX(name, load, shutdown, runtime, flags)                   \
+static const char modname[] =  #name ;                                                      \
+SWITCH_MOD_DECLARE_DATA switch_loadable_module_function_table_t name##_module_interface = { \
+    SWITCH_API_VERSION,                                                                     \
+    load,                                                                                   \
+    shutdown,                                                                               \
+    runtime,                                                                                \
+    flags                                                                                   \
+}
+
+#define SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)                             \
+        SWITCH_MODULE_DEFINITION_EX(name, load, shutdown, runtime, SMODF_NONE)
+
+
+
+switch_loadable_module_interface_t * switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name);
+
+typedef struct {
+	int id;
+	int interval;
+	int tick;
+	int samplecount;
+	int samples;
+	int diff;
+	void *private_info;
+} switch_timer_t;
+
+
+/*! \brief A table of functions that a timer module implements */
+struct switch_timer_interface {
+	/*! the name of the interface */
+	const char *interface_name;
+	/*! function to allocate the timer */
+	switch_status_t (*timer_init) (switch_timer_t *);
+	/*! function to wait for one cycle to pass */
+	switch_status_t (*timer_next) (switch_timer_t *);
+	/*! function to step the timer one step */
+	switch_status_t (*timer_step) (switch_timer_t *);
+	/*! function to reset the timer  */
+	switch_status_t (*timer_sync) (switch_timer_t *);
+	/*! function to check if the current step has expired */
+	switch_status_t (*timer_check) (switch_timer_t *, switch_bool_t);
+	/*! function to deallocate the timer */
+	switch_status_t (*timer_destroy) (switch_timer_t *);
+	int refs;
+	switch_mutex_t *reflock;
+	switch_loadable_module_interface_t *parent;
+	struct switch_timer_interface *next;
+};
+
+struct switch_loadable_module_interface {
+	switch_timer_interface_t *timer;
+};
+
+void * switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, int iname);
+
+switch_status_t switch_mutex_lock(switch_mutex_t *mutex);
+
+switch_status_t switch_mutex_unlock(switch_mutex_t *mutex);
+
+switch_status_t switch_mutex_init(switch_mutex_t **mutex, int flags, switch_memory_pool_t *pool);
+
+switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool);
+
+switch_status_t switch_thread_cond_timedwait(switch_thread_cond_t *cond, switch_mutex_t *mutex, int wait);
+
+switch_status_t switch_thread_cond_broadcast(switch_thread_cond_t *cond);
+
+void switch_log_printf(int dummy, int level, char *format, ...);
+
+#endif