summaryrefslogtreecommitdiff
path: root/pjlib/src/pjlib-test
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-05-10 19:24:40 +0000
committerBenny Prijono <bennylp@teluu.com>2006-05-10 19:24:40 +0000
commit50a501dbe89ec8f9a76540015890dd361f1ec8a1 (patch)
treea45dac4292320647ed297b35239fccf38eb5885b /pjlib/src/pjlib-test
parent5f10c756ac9d5f48efe2adbcccf5d54634540d61 (diff)
Merge-in RTEMS port patch by Phil Torre <ptorre@zetron.com>, alpha release.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@433 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src/pjlib-test')
-rw-r--r--pjlib/src/pjlib-test/ioq_tcp.c15
-rw-r--r--pjlib/src/pjlib-test/ioq_udp.c52
-rw-r--r--pjlib/src/pjlib-test/main_rtems.c325
-rw-r--r--pjlib/src/pjlib-test/pool_perf.c38
-rw-r--r--pjlib/src/pjlib-test/rtems_network_config.h148
-rw-r--r--pjlib/src/pjlib-test/sock.c27
-rw-r--r--pjlib/src/pjlib-test/test.c15
-rw-r--r--pjlib/src/pjlib-test/test.h14
-rw-r--r--pjlib/src/pjlib-test/thread.c47
-rw-r--r--pjlib/src/pjlib-test/timestamp.c16
-rw-r--r--pjlib/src/pjlib-test/util.c6
11 files changed, 648 insertions, 55 deletions
diff --git a/pjlib/src/pjlib-test/ioq_tcp.c b/pjlib/src/pjlib-test/ioq_tcp.c
index c60d614f..8f2d74d0 100644
--- a/pjlib/src/pjlib-test/ioq_tcp.c
+++ b/pjlib/src/pjlib-test/ioq_tcp.c
@@ -343,6 +343,13 @@ static int compliance_test_0(void)
callback_connect_status = -2;
}
+ if (status > pending_op) {
+ PJ_LOG(3,(THIS_FILE,
+ "...error: pj_ioqueue_poll() returned %d "
+ "(only expecting %d)",
+ status, pending_op));
+ return -52;
+ }
pending_op -= status;
if (pending_op == 0) {
@@ -478,6 +485,14 @@ static int compliance_test_1(void)
}
}
+ if (status > pending_op) {
+ PJ_LOG(3,(THIS_FILE,
+ "...error: pj_ioqueue_poll() returned %d "
+ "(only expecting %d)",
+ status, pending_op));
+ return -552;
+ }
+
pending_op -= status;
if (pending_op == 0) {
status = 0;
diff --git a/pjlib/src/pjlib-test/ioq_udp.c b/pjlib/src/pjlib-test/ioq_udp.c
index 89e2a1e8..7d00690b 100644
--- a/pjlib/src/pjlib-test/ioq_udp.c
+++ b/pjlib/src/pjlib-test/ioq_udp.c
@@ -41,6 +41,7 @@
#define THIS_FILE "test_udp"
#define PORT 51233
#define LOOP 100
+///#define LOOP 2
#define BUF_MIN_SIZE 32
#define BUF_MAX_SIZE 2048
#define SOCK_INACTIVE_MIN (1)
@@ -50,6 +51,13 @@
#undef TRACE_
#define TRACE_(msg) PJ_LOG(3,(THIS_FILE,"....." msg))
+#if 0
+# define TRACE__(args) PJ_LOG(3,args)
+#else
+# define TRACE__(args)
+#endif
+
+
static pj_ssize_t callback_read_size,
callback_write_size,
callback_accept_status,
@@ -69,6 +77,8 @@ static void on_ioqueue_read(pj_ioqueue_key_t *key,
callback_read_key = key;
callback_read_op = op_key;
callback_read_size = bytes_read;
+ TRACE__((THIS_FILE, " callback_read_key = %p, bytes=%d",
+ key, bytes_read));
}
static void on_ioqueue_write(pj_ioqueue_key_t *key,
@@ -254,7 +264,7 @@ static int compliance_test(void)
PJ_LOG(1,(THIS_FILE, "...ERROR: timed out..."));
status=-45; goto on_error;
} else if (rc < 0) {
- app_perror("...ERROR in ioqueue_poll()", rc);
+ app_perror("...ERROR in ioqueue_poll()", -rc);
status=-50; goto on_error;
}
@@ -492,7 +502,7 @@ static int many_handles_test(void)
pj_sock_t *sock;
pj_ioqueue_key_t **key;
pj_status_t rc;
- int count, i;
+ int count, i; /* must be signed */
PJ_LOG(3,(THIS_FILE,"...testing with so many handles"));
@@ -533,7 +543,19 @@ static int many_handles_test(void)
/* Now deregister and close all handles. */
- for (i=0; i<count; ++i) {
+ /* NOTE for RTEMS:
+ * It seems that the order of close(sock) is pretty important here.
+ * If we close the sockets with the same order as when they were created,
+ * RTEMS doesn't seem to reuse the sockets, thus next socket created
+ * will have descriptor higher than the last socket created.
+ * If we close the sockets in the reverse order, then the descriptor will
+ * get reused.
+ * This used to cause problem with select ioqueue, since the ioqueue
+ * always gives FD_SETSIZE for the first select() argument. This ioqueue
+ * behavior can be changed with setting PJ_SELECT_NEEDS_NFDS macro.
+ */
+ for (i=count-1; i>=0; --i) {
+ ///for (i=0; i<count; ++i) {
rc = pj_ioqueue_unregister(key[i]);
if (rc != PJ_SUCCESS) {
app_perror("...error in pj_ioqueue_unregister", rc);
@@ -570,9 +592,11 @@ static int bench_test(int bufsize, int inactive_sock_count)
pj_ioqueue_t *ioque = NULL;
pj_ioqueue_key_t *skey, *ckey, *key;
pj_timestamp t1, t2, t_elapsed;
- int rc=0, i;
+ int rc=0, i; /* i must be signed */
pj_str_t temp;
- char errbuf[128];
+ char errbuf[PJ_ERR_MSG_SIZE];
+
+ TRACE__((THIS_FILE, " bench test %d", inactive_sock_count));
// Create pool.
pool = pj_pool_create(mem, NULL, POOL_SIZE, 4000, NULL);
@@ -691,9 +715,15 @@ static int bench_test(int bufsize, int inactive_sock_count)
rc = pj_ioqueue_sendto(ckey, &write_op, send_buf, &bytes, 0,
&addr, sizeof(addr));
if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
- app_perror("...error: pj_ioqueue_write()", bytes);
+ app_perror("...error: pj_ioqueue_write()", rc);
break;
}
+ if (rc == PJ_SUCCESS) {
+ if (bytes < 0) {
+ app_perror("...error: pj_ioqueue_sendto()", -bytes);
+ break;
+ }
+ }
// Begin time.
pj_get_timestamp(&t1);
@@ -701,8 +731,11 @@ static int bench_test(int bufsize, int inactive_sock_count)
// Poll the queue until we've got completion event in the server side.
callback_read_key = NULL;
callback_read_size = 0;
+ TRACE__((THIS_FILE, " waiting for key = %p", skey));
do {
- rc = pj_ioqueue_poll(ioque, NULL);
+ pj_time_val timeout = { 1, 0 };
+ rc = pj_ioqueue_poll(ioque, &timeout);
+ TRACE__((THIS_FILE, " poll rc=%d", rc));
} while (rc >= 0 && callback_read_key != skey);
// End time.
@@ -749,11 +782,14 @@ static int bench_test(int bufsize, int inactive_sock_count)
}
// Cleaning up.
- for (i=0; i<inactive_sock_count; ++i)
+ for (i=inactive_sock_count-1; i>=0; --i) {
pj_sock_close(inactive_sock[i]);
+ }
+
pj_sock_close(ssock);
pj_sock_close(csock);
+
pj_ioqueue_destroy(ioque);
pj_pool_release( pool);
return rc;
diff --git a/pjlib/src/pjlib-test/main_rtems.c b/pjlib/src/pjlib-test/main_rtems.c
new file mode 100644
index 00000000..963cdc4e
--- /dev/null
+++ b/pjlib/src/pjlib-test/main_rtems.c
@@ -0,0 +1,325 @@
+/* $Id$ */
+/*
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * - Many thanks for Zetron, Inc. and Phil Torre <ptorre@zetron.com> for
+ * donating this file and the RTEMS port in general!
+ */
+
+#include "test.h"
+
+#include <pj/errno.h>
+#include <pj/string.h>
+#include <pj/sock.h>
+#include <pj/log.h>
+
+extern int param_echo_sock_type;
+extern const char *param_echo_server;
+extern int param_echo_port;
+
+#include <bsp.h>
+
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 300
+#define CONFIGURE_MAXIMUM_TASKS 50
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES rtems_resource_unlimited(10)
+#define CONFIGURE_MAXIMUM_SEMAPHORES rtems_resource_unlimited(10)
+#define CONFIGURE_MAXIMUM_TIMERS 50
+#define CONFIGURE_MAXIMUM_REGIONS 3
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
+#define CONFIGURE_TICKS_PER_TIMESLICE 2
+//#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+
+#define CONFIGURE_MAXIMUM_POSIX_MUTEXES rtems_resource_unlimited(16)
+#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES rtems_resource_unlimited(5)
+#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES rtems_resource_unlimited(16)
+#define CONFIGURE_MAXIMUM_POSIX_TIMERS rtems_resource_unlimited(5)
+#define CONFIGURE_MAXIMUM_POSIX_THREADS rtems_resource_unlimited(16)
+#define CONFIGURE_MAXIMUM_POSIX_KEYS rtems_resource_unlimited(16)
+
+#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE 4096
+
+/* Make sure that stack size is at least 4096 */
+#define SZ (4096-RTEMS_MINIMUM_STACK_SIZE)
+#define CONFIGURE_EXTRA_TASK_STACKS ((SZ)<0 ? 0 : (SZ))
+
+#define CONFIGURE_INIT
+#define STACK_CHECKER_ON
+
+rtems_task Init(rtems_task_argument Argument) ;
+void *POSIX_Init(void *argument);
+
+#include <confdefs.h>
+#include <rtems.h>
+
+/* Any tests that want to build a linked executable for RTEMS must include
+ these headers to get a default config for the network stack. */
+#include <rtems/rtems_bsdnet.h>
+#include "rtems_network_config.h"
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define THIS_FILE "main_rtems.c"
+
+static void* pjlib_test_main(void* unused);
+static void initialize_network();
+static void test_sock(void);
+
+static void my_perror(pj_status_t status, const char *title)
+{
+ char err[PJ_ERR_MSG_SIZE];
+
+ pj_strerror(status, err, sizeof(err));
+ printf("%s: %s [%d]\n", title, err, status);
+}
+
+#define TEST(expr) { int rc;\
+ /*PJ_LOG(3,(THIS_FILE,"%s", #expr));*/ \
+ /*sleep(1);*/ \
+ rc=expr; \
+ if (rc) my_perror(PJ_STATUS_FROM_OS(rc),#expr); }
+
+
+
+//rtems_task Init(rtems_task_argument Argument)
+void *POSIX_Init(void *argument)
+{
+ pthread_attr_t threadAttr;
+ pthread_t theThread;
+ struct sched_param sched_param;
+ size_t stack_size;
+ int result;
+ char data[1000];
+
+
+ memset(data, 1, sizeof(data));
+
+ /* Set the TOD clock, so that gettimeofday() will work */
+ rtems_time_of_day fakeTime = { 2006, 3, 15, 17, 30, 0, 0 };
+
+ if (RTEMS_SUCCESSFUL != rtems_clock_set(&fakeTime))
+ {
+ assert(0);
+ }
+
+ /* Bring up the network stack so we can run the socket tests. */
+ initialize_network();
+
+ /* Start a POSIX thread for pjlib_test_main(), since that's what it
+ * thinks it is running in.
+ */
+
+ /* Initialize attribute */
+ TEST( pthread_attr_init(&threadAttr) );
+
+ /* Looks like the rest of the attributes must be fully initialized too,
+ * or otherwise pthread_create will return EINVAL.
+ */
+
+ /* Specify explicit scheduling request */
+ TEST( pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED));
+
+ /* Timeslicing is needed by thread test, and this is accomplished by
+ * SCHED_RR.
+ */
+ TEST( pthread_attr_setschedpolicy(&threadAttr, SCHED_RR));
+
+ /* Set priority */
+ TEST( pthread_attr_getschedparam(&threadAttr, &sched_param));
+ sched_param.sched_priority = NETWORK_STACK_PRIORITY - 10;
+ TEST( pthread_attr_setschedparam(&threadAttr, &sched_param));
+
+ /* Must have sufficient stack size (large size is needed by
+ * logger, because default settings for logger is to use message buffer
+ * from the stack).
+ */
+ TEST( pthread_attr_getstacksize(&threadAttr, &stack_size));
+ if (stack_size < 8192)
+ TEST( pthread_attr_setstacksize(&threadAttr, 8192));
+
+
+ /* Create the thread for application */
+ result = pthread_create(&theThread, &threadAttr, &pjlib_test_main, NULL);
+ if (result != 0) {
+ my_perror(PJ_STATUS_FROM_OS(result),
+ "Error creating pjlib_test_main thread");
+ assert(!"Error creating main thread");
+ }
+
+ return NULL;
+}
+
+
+
+#define boost()
+#define init_signals()
+
+static void*
+pjlib_test_main(void* unused)
+{
+ int rc;
+
+ /* Drop our priority to below that of the network stack, otherwise
+ * select() tests will fail. */
+ struct sched_param schedParam;
+ int schedPolicy;
+
+ printf("pjlib_test_main thread started..\n");
+
+ TEST( pthread_getschedparam(pthread_self(), &schedPolicy, &schedParam) );
+
+ schedParam.sched_priority = NETWORK_STACK_PRIORITY - 10;
+
+ TEST( pthread_setschedparam(pthread_self(), schedPolicy, &schedParam) );
+
+ boost();
+ init_signals();
+
+ //my_test_thread("from pjlib_test_main");
+ //test_sock();
+
+ rc = test_main();
+
+ return (void*)rc;
+}
+
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <unistd.h>
+
+/*
+ * Send UDP packet to some host. We can then use Ethereal to sniff the packet
+ * to see if this target really transmits UDP packet.
+ */
+static void
+send_udp(const char *target)
+{
+ int sock, rc;
+ struct sockaddr_in addr;
+
+ PJ_LOG(3,("main_rtems.c", "IP addr=%s/%s, gw=%s",
+ DEFAULT_IP_ADDRESS_STRING,
+ DEFAULT_NETMASK_STRING,
+ DEFAULT_GATEWAY_STRING));
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ assert(sock > 0);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+
+ rc = bind(sock, (struct sockaddr*)&addr, sizeof(addr));
+ assert("bind error" && rc==0);
+
+ addr.sin_addr.s_addr = inet_addr(target);
+ addr.sin_port = htons(4444);
+
+ while(1) {
+ const char *data = "hello";
+
+ rc = sendto(sock, data, 5, 0, (struct sockaddr*)&addr, sizeof(addr));
+ PJ_LOG(3,("main_rtems.c", "pinging %s..(rc=%d)", target, rc));
+ sleep(1);
+ }
+}
+
+
+static void test_sock(void)
+{
+ int sock;
+ struct sockaddr_in addr;
+ int rc;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ printf("socket() error\n");
+ goto end;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ addr.sin_port = htons(5000);
+
+ rc = bind(sock, (struct sockaddr*)&addr, sizeof(addr));
+ if (rc != 0) {
+ printf("bind() error %d\n", rc);
+ close(sock);
+ goto end;
+ }
+
+ puts("Bind socket success");
+
+ close(sock);
+
+end:
+ while(1) sleep(1);
+}
+
+/*
+ * Initialize the network stack and Ethernet driver, using the configuration
+ * in rtems-network-config.h
+ */
+static void
+initialize_network()
+{
+ unsigned32 fd, result;
+ char ip_address_string[] = DEFAULT_IP_ADDRESS_STRING;
+ char netmask_string[] = DEFAULT_NETMASK_STRING;
+ char gateway_string[] = DEFAULT_GATEWAY_STRING;
+
+ // Write the network config files to /etc/hosts and /etc/host.conf
+ result = mkdir("/etc", S_IRWXU | S_IRWXG | S_IRWXO);
+ fd = open("/etc/host.conf", O_RDWR | O_CREAT, 0744);
+ result = write(fd, "hosts,bind\n", 11);
+ result = close(fd);
+ fd = open("/etc/hosts", O_RDWR | O_CREAT, 0744);
+ result = write(fd, "127.0.0.1 localhost\n", 41);
+ result = write(fd, ip_address_string, strlen(ip_address_string));
+ result = write(fd, " pjsip-test\n", 32);
+ result = close(fd);
+
+ netdriver_config.ip_address = ip_address_string;
+ netdriver_config.ip_netmask = netmask_string;
+ rtems_bsdnet_config.gateway = gateway_string;
+
+ if (0 != rtems_bsdnet_initialize_network())
+ PJ_LOG(3,(THIS_FILE, "Error: Unable to initialize network stack!"));
+ else
+ PJ_LOG(3,(THIS_FILE, "IP addr=%s/%s, gw=%s",
+ ip_address_string,
+ netmask_string,
+ gateway_string));
+
+ //rtems_rdbg_initialize();
+ //enterRdbg();
+ //send_udp("192.168.0.1");
+ //test_sock();
+}
+
+
diff --git a/pjlib/src/pjlib-test/pool_perf.c b/pjlib/src/pjlib-test/pool_perf.c
index 6bc6dcfb..07782995 100644
--- a/pjlib/src/pjlib-test/pool_perf.c
+++ b/pjlib/src/pjlib-test/pool_perf.c
@@ -32,10 +32,12 @@
#define LOOP 10
#define COUNT 1024
static unsigned sizes[COUNT];
+static char *p[COUNT];
#define MIN_SIZE 4
#define MAX_SIZE 512
static unsigned total_size;
+
static int pool_test_pool()
{
int i;
@@ -45,8 +47,12 @@ static int pool_test_pool()
for (i=0; i<COUNT; ++i) {
char *p;
- if ( (p=(char*)pj_pool_alloc(pool, sizes[i])) == NULL)
+ if ( (p=(char*)pj_pool_alloc(pool, sizes[i])) == NULL) {
+ PJ_LOG(3,(THIS_FILE," error: pool failed to allocate %d bytes",
+ sizes[i]));
+ pj_pool_release(pool);
return -1;
+ }
*p = '\0';
}
@@ -56,13 +62,16 @@ static int pool_test_pool()
static int pool_test_malloc_free()
{
- char *p[COUNT];
- int i;
+ int i; /* must be signed */
for (i=0; i<COUNT; ++i) {
p[i] = (char*)malloc(sizes[i]);
if (!p[i]) {
- // Don't care for memory leak in this test
+ PJ_LOG(3,(THIS_FILE," error: malloc failed to allocate %d bytes",
+ sizes[i]));
+ --i;
+ while (i >= 0)
+ free(p[i]), --i;
return -1;
}
*p[i] = '\0';
@@ -82,15 +91,18 @@ int pool_perf_test()
pj_timestamp start, end;
pj_uint32_t best, worst;
- // Initialize sizes.
+ /* Initialize size of chunks to allocate in for the test. */
for (i=0; i<COUNT; ++i) {
- sizes[i] = MIN_SIZE + pj_rand() % MAX_SIZE;
+ sizes[i] = MIN_SIZE + (pj_rand() % MAX_SIZE);
total_size += sizes[i];
}
+ /* Add some more for pool admin area */
+ total_size += 512;
+
PJ_LOG(3, (THIS_FILE, "Benchmarking pool.."));
- // Warmup
+ /* Warmup */
pool_test_pool();
pool_test_malloc_free();
@@ -117,11 +129,11 @@ int pool_perf_test()
pool_time2 += (end.u32.lo - start.u32.lo);
}
- PJ_LOG(4, (THIS_FILE, "..LOOP count: %u", LOOP));
- PJ_LOG(4, (THIS_FILE, "..number of alloc/dealloc per loop: %u", COUNT));
- PJ_LOG(4, (THIS_FILE, "..pool allocation/deallocation time: %u", pool_time));
- PJ_LOG(4, (THIS_FILE, "..malloc/free time: %u", malloc_time));
- PJ_LOG(4, (THIS_FILE, "..pool again, second invocation: %u", pool_time2));
+ PJ_LOG(4,(THIS_FILE,"..LOOP count: %u",LOOP));
+ PJ_LOG(4,(THIS_FILE,"..number of alloc/dealloc per loop: %u",COUNT));
+ PJ_LOG(4,(THIS_FILE,"..pool allocation/deallocation time: %u",pool_time));
+ PJ_LOG(4,(THIS_FILE,"..malloc/free time: %u",malloc_time));
+ PJ_LOG(4,(THIS_FILE,"..pool again, second invocation: %u",pool_time2));
if (pool_time2==0) pool_time2=1;
if (pool_time < pool_time2)
@@ -129,7 +141,7 @@ int pool_perf_test()
else
best = pool_time2, worst = pool_time;
- PJ_LOG(3, (THIS_FILE, "..malloc Speedup best=%dx, worst=%dx",
+ PJ_LOG(3, (THIS_FILE, "..pool speedup over malloc best=%dx, worst=%dx",
(int)(malloc_time/best),
(int)(malloc_time/worst)));
return 0;
diff --git a/pjlib/src/pjlib-test/rtems_network_config.h b/pjlib/src/pjlib-test/rtems_network_config.h
new file mode 100644
index 00000000..b95a15b5
--- /dev/null
+++ b/pjlib/src/pjlib-test/rtems_network_config.h
@@ -0,0 +1,148 @@
+/* $Id$ */
+/*
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Thanks Zetron, Inc and Phil Torre <ptorre@zetron.com> for donating PJLIB
+ * port to RTEMS.
+ */
+
+/*
+ * Network configuration
+ *
+ ************************************************************
+ * EDIT THIS FILE TO REFLECT YOUR NETWORK CONFIGURATION *
+ * BEFORE RUNNING ANY RTEMS PROGRAMS WHICH USE THE NETWORK! *
+ ************************************************************
+ *
+ */
+
+#ifndef _RTEMS_NETWORKCONFIG_H_
+#define _RTEMS_NETWORKCONFIG_H_
+
+
+#define DEFAULT_IP_ADDRESS_STRING "192.168.0.2"
+#define DEFAULT_NETMASK_STRING "255.255.255.0"
+#define DEFAULT_GATEWAY_STRING "192.168.0.1"
+
+
+
+
+#ifndef RTEMS_BSP_NETWORK_DRIVER_NAME
+#warning "RTEMS_BSP_NETWORK_DRIVER_NAME is not defined"
+#define RTEMS_BSP_NETWORK_DRIVER_NAME "no_network1"
+#endif
+
+#ifndef RTEMS_BSP_NETWORK_DRIVER_ATTACH
+#warning "RTEMS_BSP_NETWORK_DRIVER_ATTACH is not defined"
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH 0
+#endif
+
+#define NETWORK_STACK_PRIORITY 128
+/* #define RTEMS_USE_BOOTP */
+
+/* #define RTEMS_USE_LOOPBACK */
+
+#include <bsp.h>
+
+/*
+ * Define RTEMS_SET_ETHERNET_ADDRESS if you want to specify the
+ * Ethernet address here. If RTEMS_SET_ETHERNET_ADDRESS is not
+ * defined the driver will choose an address.
+ */
+// NOTE: The address below is a dummy address that should only ever
+// be used for testing on a private network. DO NOT LET A PRODUCT
+// CONTAINING THIS ETHERNET ADDRESS OUT INTO THE FIELD!
+//#define RTEMS_SET_ETHERNET_ADDRESS
+#if (defined (RTEMS_SET_ETHERNET_ADDRESS))
+static char ethernet_address[6] = { 0x00, 0x80, 0x7F, 0x22, 0x61, 0x77 };
+#endif
+
+#define RTEMS_USE_LOOPBACK
+#ifdef RTEMS_USE_LOOPBACK
+/*
+ * Loopback interface
+ */
+extern int rtems_bsdnet_loopattach(struct rtems_bsdnet_ifconfig* dummy, int unused);
+static struct rtems_bsdnet_ifconfig loopback_config = {
+ "lo0", /* name */
+ rtems_bsdnet_loopattach, /* attach function */
+ NULL, /* link to next interface */
+ "127.0.0.1", /* IP address */
+ "255.0.0.0", /* IP net mask */
+};
+#endif
+
+/*
+ * Default network interface
+ */
+static struct rtems_bsdnet_ifconfig netdriver_config = {
+ RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */
+ RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */
+
+#ifdef RTEMS_USE_LOOPBACK
+ &loopback_config, /* link to next interface */
+#else
+ NULL, /* No more interfaces */
+#endif
+
+#if (defined (RTEMS_USE_BOOTP))
+ NULL, /* BOOTP supplies IP address */
+ NULL, /* BOOTP supplies IP net mask */
+#else
+ "192.168.0.33", /* IP address */
+ "255.255.255.0", /* IP net mask */
+#endif /* !RTEMS_USE_BOOTP */
+
+#if (defined (RTEMS_SET_ETHERNET_ADDRESS))
+ ethernet_address, /* Ethernet hardware address */
+#else
+ NULL, /* Driver supplies hardware address */
+#endif
+ 0 /* Use default driver parameters */
+};
+
+/*
+ * Network configuration
+ */
+struct rtems_bsdnet_config rtems_bsdnet_config = {
+ &netdriver_config,
+
+#if (defined (RTEMS_USE_BOOTP))
+ rtems_bsdnet_do_bootp,
+#else
+ NULL,
+#endif
+
+ NETWORK_STACK_PRIORITY, /* Default network task priority */
+ 1048576, /* Default mbuf capacity */
+ 1048576, /* Default mbuf cluster capacity */
+
+#if (!defined (RTEMS_USE_BOOTP))
+ "testnode", /* Host name */
+ "example.org", /* Domain name */
+ "192.168.6.9", /* Gateway */
+ "192.168.7.41", /* Log host */
+ {"198.137.231.1" }, /* Name server(s) */
+ {"207.202.190.162" }, /* NTP server(s) */
+#endif /* !RTEMS_USE_BOOTP */
+
+};
+
+#endif /* _RTEMS_NETWORKCONFIG_H_ */
+
diff --git a/pjlib/src/pjlib-test/sock.c b/pjlib/src/pjlib-test/sock.c
index b8af3cd8..fb689169 100644
--- a/pjlib/src/pjlib-test/sock.c
+++ b/pjlib/src/pjlib-test/sock.c
@@ -63,14 +63,20 @@
#define UDP_PORT 51234
#define TCP_PORT (UDP_PORT+10)
#define BIG_DATA_LEN 9000
+#define ADDRESS "127.0.0.1"
+#define A0 127
+#define A1 0
+#define A2 0
+#define A3 1
+
static char bigdata[BIG_DATA_LEN];
static char bigbuffer[BIG_DATA_LEN];
static int format_test(void)
{
- pj_str_t s = pj_str("127.0.0.1");
- char *p;
+ pj_str_t s = pj_str(ADDRESS);
+ unsigned char *p;
pj_in_addr addr;
const pj_str_t *hostname;
@@ -81,9 +87,13 @@ static int format_test(void)
return -10;
/* Check the result. */
- p = (char*)&addr;
- if (p[0]!=127 || p[1]!=0 || p[2]!=0 || p[3]!=1)
+ p = (unsigned char*)&addr;
+ if (p[0]!=A0 || p[1]!=A1 || p[2]!=A2 || p[3]!=A3) {
+ PJ_LOG(3,("test", " error: mismatched address. p0=%d, p1=%d, "
+ "p2=%d, p3=%d", p[0] & 0xFF, p[1] & 0xFF,
+ p[2] & 0xFF, p[3] & 0xFF));
return -15;
+ }
/* pj_inet_ntoa() */
p = pj_inet_ntoa(addr);
@@ -98,6 +108,9 @@ static int format_test(void)
if (!hostname || !hostname->ptr || !hostname->slen)
return -40;
+ PJ_LOG(3,("test", "....hostname is %.*s",
+ (int)hostname->slen, hostname->ptr));
+
/* pj_gethostaddr() */
return 0;
@@ -313,10 +326,10 @@ static int udp_test(void)
pj_memset(&dstaddr, 0, sizeof(dstaddr));
dstaddr.sin_family = PJ_AF_INET;
dstaddr.sin_port = pj_htons(UDP_PORT);
- dstaddr.sin_addr = pj_inet_addr(pj_cstr(&s, "127.0.0.1"));
+ dstaddr.sin_addr = pj_inet_addr(pj_cstr(&s, ADDRESS));
if ((rc=pj_sock_bind(ss, &dstaddr, sizeof(dstaddr))) != 0) {
- app_perror("...bind error", rc);
+ app_perror("...bind error udp:"ADDRESS, rc);
rc = -120; goto on_error;
}
@@ -324,7 +337,7 @@ static int udp_test(void)
pj_memset(&srcaddr, 0, sizeof(srcaddr));
srcaddr.sin_family = PJ_AF_INET;
srcaddr.sin_port = pj_htons(UDP_PORT-1);
- srcaddr.sin_addr = pj_inet_addr(pj_cstr(&s, "127.0.0.1"));
+ srcaddr.sin_addr = pj_inet_addr(pj_cstr(&s, ADDRESS));
if ((rc=pj_sock_bind(cs, &srcaddr, sizeof(srcaddr))) != 0) {
app_perror("...bind error", rc);
diff --git a/pjlib/src/pjlib-test/test.c b/pjlib/src/pjlib-test/test.c
index 97ba2991..01eeb3c6 100644
--- a/pjlib/src/pjlib-test/test.c
+++ b/pjlib/src/pjlib-test/test.c
@@ -40,6 +40,11 @@ int param_echo_port = ECHO_SERVER_START_PORT;
int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
PJ_LOG_HAS_MICRO_SEC;
+int null_func()
+{
+ return 0;
+}
+
int test_inner(void)
{
pj_caching_pool caching_pool;
@@ -58,17 +63,13 @@ int test_inner(void)
return rc;
}
- pj_dump_config();
+ //pj_dump_config();
pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0 );
#if INCLUDE_ERRNO_TEST
DO_TEST( errno_test() );
#endif
-#if INCLUDE_TIMESTAMP_TEST
- DO_TEST( timestamp_test() );
-#endif
-
#if INCLUDE_EXCEPTION_TEST
DO_TEST( exception_test() );
#endif
@@ -101,6 +102,10 @@ int test_inner(void)
DO_TEST( rbtree_test() );
#endif
+#if INCLUDE_TIMESTAMP_TEST
+ DO_TEST( timestamp_test() );
+#endif
+
#if INCLUDE_ATOMIC_TEST
DO_TEST( atomic_test() );
#endif
diff --git a/pjlib/src/pjlib-test/test.h b/pjlib/src/pjlib-test/test.h
index 7a0aeed2..78478df6 100644
--- a/pjlib/src/pjlib-test/test.h
+++ b/pjlib/src/pjlib-test/test.h
@@ -21,11 +21,11 @@
#include <pj/types.h>
-#define GROUP_LIBC 1
-#define GROUP_OS 1
-#define GROUP_DATA_STRUCTURE 1
-#define GROUP_NETWORK 1
-#define GROUP_FILE 1
+#define GROUP_LIBC 0
+#define GROUP_OS 0
+#define GROUP_DATA_STRUCTURE 0
+#define GROUP_NETWORK 0
+#define GROUP_FILE 0
#define INCLUDE_ERRNO_TEST GROUP_LIBC
#define INCLUDE_TIMESTAMP_TEST GROUP_OS
@@ -48,7 +48,7 @@
#define INCLUDE_UDP_IOQUEUE_TEST GROUP_NETWORK
#define INCLUDE_TCP_IOQUEUE_TEST GROUP_NETWORK
#define INCLUDE_IOQUEUE_PERF_TEST GROUP_NETWORK
-#define INCLUDE_IOQUEUE_UNREG_TEST GROUP_NETWORK
+#define INCLUDE_IOQUEUE_UNREG_TEST 1 // GROUP_NETWORK
#define INCLUDE_FILE_TEST GROUP_FILE
#define INCLUDE_ECHO_SERVER 0
@@ -103,9 +103,11 @@ extern pj_status_t app_socket(int family, int type, int proto, int port,
pj_sock_t *ptr_sock);
extern pj_status_t app_socketpair(int family, int type, int protocol,
pj_sock_t *server, pj_sock_t *client);
+extern int null_func(void);
//#define TRACE_(expr) PJ_LOG(3,expr)
#define TRACE_(expr)
+#define HALT(msg) { PJ_LOG(3,(THIS_FILE,"%s halted",msg)); for(;;) sleep(1); }
PJ_END_DECL
diff --git a/pjlib/src/pjlib-test/thread.c b/pjlib/src/pjlib-test/thread.c
index 72cb2ecd..866c7698 100644
--- a/pjlib/src/pjlib-test/thread.c
+++ b/pjlib/src/pjlib-test/thread.c
@@ -52,7 +52,14 @@
#define THIS_FILE "thread_test"
-static int quit_flag=0;
+static volatile int quit_flag=0;
+
+#if 0
+# define TRACE__(args) PJ_LOG(3,args)
+#else
+# define TRACE__(args)
+#endif
+
/*
* The thread's entry point.
@@ -65,8 +72,11 @@ static void* thread_proc(pj_uint32_t *pcounter)
/* Test that pj_thread_register() works. */
pj_thread_desc desc;
pj_thread_t *this_thread;
+ unsigned id = *pcounter;
pj_status_t rc;
+ TRACE__((THIS_FILE, " thread %d running..", id));
+
rc = pj_thread_register("thread", desc, &this_thread);
if (rc != PJ_SUCCESS) {
app_perror("...error in pj_thread_register", rc);
@@ -90,9 +100,10 @@ static void* thread_proc(pj_uint32_t *pcounter)
for (;!quit_flag;) {
(*pcounter)++;
//Must sleep if platform doesn't do time-slicing.
- pj_thread_sleep(0);
+ //pj_thread_sleep(0);
}
+ TRACE__((THIS_FILE, " thread %d quitting..", id));
return NULL;
}
@@ -114,6 +125,7 @@ static int simple_thread(const char *title, unsigned flags)
quit_flag = 0;
+ TRACE__((THIS_FILE, " Creating thread 0.."));
rc = pj_thread_create(pool, "thread", (pj_thread_proc*)&thread_proc,
&counter,
PJ_THREAD_DEFAULT_STACK_SIZE,
@@ -125,7 +137,9 @@ static int simple_thread(const char *title, unsigned flags)
return -1010;
}
- pj_thread_sleep(500);
+ TRACE__((THIS_FILE, " Main thread waiting.."));
+ pj_thread_sleep(1500);
+ TRACE__((THIS_FILE, " Main thread resuming.."));
if (flags & PJ_THREAD_SUSPENDED) {
@@ -144,7 +158,7 @@ static int simple_thread(const char *title, unsigned flags)
PJ_LOG(3,(THIS_FILE, "..waiting for thread to quit.."));
- pj_thread_sleep(500);
+ pj_thread_sleep(1500);
quit_flag = 1;
pj_thread_join(thread);
@@ -175,7 +189,7 @@ static int timeslice_test(void)
quit_flag = 0;
- pool = pj_pool_create(mem, NULL, 4096, 0, NULL);
+ pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
if (!pool)
return -10;
@@ -183,7 +197,7 @@ static int timeslice_test(void)
/* Create all threads in suspended mode. */
for (i=0; i<NUM_THREADS; ++i) {
- counter[i] = 0;
+ counter[i] = i;
rc = pj_thread_create(pool, "thread", (pj_thread_proc*)&thread_proc,
&counter[i],
PJ_THREAD_DEFAULT_STACK_SIZE,
@@ -198,11 +212,13 @@ static int timeslice_test(void)
/* Sleep for 1 second.
* The purpose of this is to test whether all threads are suspended.
*/
+ TRACE__((THIS_FILE, " Main thread waiting.."));
pj_thread_sleep(1000);
+ TRACE__((THIS_FILE, " Main thread resuming.."));
/* Check that all counters are still zero. */
for (i=0; i<NUM_THREADS; ++i) {
- if (counter[i] != 0) {
+ if (counter[i] > i) {
PJ_LOG(3,(THIS_FILE, "....ERROR! Thread %d-th is not suspended!",
i));
return -30;
@@ -211,6 +227,7 @@ static int timeslice_test(void)
/* Now resume all threads. */
for (i=0; i<NUM_THREADS; ++i) {
+ TRACE__((THIS_FILE, " Resuming thread %d [%p]..", i, thread[i]));
rc = pj_thread_resume(thread[i]);
if (rc != PJ_SUCCESS) {
app_perror("...ERROR in pj_thread_resume()", rc);
@@ -222,18 +239,23 @@ static int timeslice_test(void)
* The longer we sleep, the more accurate the calculation will be,
* but it'll make user waits for longer for the test to finish.
*/
+ TRACE__((THIS_FILE, " Main thread waiting (5s).."));
pj_thread_sleep(5000);
+ TRACE__((THIS_FILE, " Main thread resuming.."));
/* Signal all threads to quit. */
quit_flag = 1;
/* Wait until all threads quit, then destroy. */
for (i=0; i<NUM_THREADS; ++i) {
+ TRACE__((THIS_FILE, " Main thread joining thread %d [%p]..",
+ i, thread[i]));
rc = pj_thread_join(thread[i]);
if (rc != PJ_SUCCESS) {
app_perror("...ERROR in pj_thread_join()", rc);
return -50;
}
+ TRACE__((THIS_FILE, " Destroying thread %d [%p]..", i, thread[i]));
rc = pj_thread_destroy(thread[i]);
if (rc != PJ_SUCCESS) {
app_perror("...ERROR in pj_thread_destroy()", rc);
@@ -241,6 +263,8 @@ static int timeslice_test(void)
}
}
+ TRACE__((THIS_FILE, " Main thread calculating time slices.."));
+
/* Now examine the value of the counters.
* Check that all threads had equal proportion of processing.
*/
@@ -263,9 +287,11 @@ static int timeslice_test(void)
*/
diff = (highest-lowest)*100 / ((highest+lowest)/2);
if ( diff >= 50) {
- PJ_LOG(3,(THIS_FILE, "...ERROR: thread didn't have equal timeslice!"));
- PJ_LOG(3,(THIS_FILE, ".....lowest counter=%u, highest counter=%u, diff=%u%%",
- lowest, highest, diff));
+ PJ_LOG(3,(THIS_FILE,
+ "...ERROR: thread didn't have equal timeslice!"));
+ PJ_LOG(3,(THIS_FILE,
+ ".....lowest counter=%u, highest counter=%u, diff=%u%%",
+ lowest, highest, diff));
return -80;
} else {
PJ_LOG(3,(THIS_FILE,
@@ -273,6 +299,7 @@ static int timeslice_test(void)
diff));
}
+ pj_pool_release(pool);
return 0;
}
diff --git a/pjlib/src/pjlib-test/timestamp.c b/pjlib/src/pjlib-test/timestamp.c
index 48435406..f7ff7874 100644
--- a/pjlib/src/pjlib-test/timestamp.c
+++ b/pjlib/src/pjlib-test/timestamp.c
@@ -188,8 +188,14 @@ int timestamp_test(void)
}
/* Loop.. */
- for (i=0; i<1000000; ++i)
- ;
+ for (i=0; i<1000000; ++i) {
+ /* Try to do something so that smart compilers wont
+ * remove this silly loop.
+ */
+ null_func();
+ }
+
+ sleep(0);
/* Mark end time. */
pj_get_timestamp(&t2);
@@ -198,8 +204,10 @@ int timestamp_test(void)
elapsed = pj_elapsed_usec(&t1, &t2);
PJ_LOG(3,(THIS_FILE, "....elapsed: %u usec", (unsigned)elapsed));
- /* See if elapsed time is reasonable. */
- if (elapsed < 1 || elapsed > 100000) {
+ /* See if elapsed time is "reasonable".
+ * This should be good even on 50Mhz embedded powerpc.
+ */
+ if (elapsed < 1 || elapsed > 1000000) {
PJ_LOG(3,(THIS_FILE, "....error: elapsed time outside window (%u, "
"t1.u32.hi=%u, t1.u32.lo=%u, "
"t2.u32.hi=%u, t2.u32.lo=%u)",
diff --git a/pjlib/src/pjlib-test/util.c b/pjlib/src/pjlib-test/util.c
index 19b769cb..ea1d4652 100644
--- a/pjlib/src/pjlib-test/util.c
+++ b/pjlib/src/pjlib-test/util.c
@@ -19,14 +19,16 @@
#include "test.h"
#include <pjlib.h>
+#define THIS_FILE "util.c"
+
void app_perror(const char *msg, pj_status_t rc)
{
- char errbuf[256];
+ char errbuf[PJ_ERR_MSG_SIZE];
PJ_CHECK_STACK();
pj_strerror(rc, errbuf, sizeof(errbuf));
- PJ_LOG(1,("test", "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
+ PJ_LOG(3,("test", "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
}
#define SERVER 0