diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-05-10 19:24:40 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-05-10 19:24:40 +0000 |
commit | 50a501dbe89ec8f9a76540015890dd361f1ec8a1 (patch) | |
tree | a45dac4292320647ed297b35239fccf38eb5885b /pjlib/src/pjlib-test | |
parent | 5f10c756ac9d5f48efe2adbcccf5d54634540d61 (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.c | 15 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/ioq_udp.c | 52 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/main_rtems.c | 325 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/pool_perf.c | 38 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/rtems_network_config.h | 148 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/sock.c | 27 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/test.c | 15 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/test.h | 14 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/thread.c | 47 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/timestamp.c | 16 | ||||
-rw-r--r-- | pjlib/src/pjlib-test/util.c | 6 |
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 |