Merge-in RTEMS port patch by Phil Torre <ptorre@zetron.com>, alpha release.
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@433 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
7a6e84fc2c
commit
42c5b9e200
|
@ -0,0 +1,47 @@
|
|||
|
||||
Configuring the Build System
|
||||
Update: 04 May 2006
|
||||
|
||||
|
||||
1. Overview
|
||||
|
||||
The "configure" script in pjproject root directory is not an autoconf script,
|
||||
but it's just a custom script to generate "build.mak" for the build system.
|
||||
The "build.mak" file declares the following global Makefile variables:
|
||||
|
||||
MACHINE_NAME
|
||||
The processor and hardware platform of the target. For each MACHINE_NAME,
|
||||
there must be matching "m-*.mak" entry in "build/" subdirectory. For
|
||||
example, when MACHINE_NAME is declared as "i386", then there must be
|
||||
"m-i386.mak" file in "build/" subdirectory.
|
||||
|
||||
OS_NAME
|
||||
Operating system name, determines which "os-*.mak" in "build/" dir to use.
|
||||
|
||||
HOST_NAME
|
||||
Build host name, determines which "host-*.mak" to use.
|
||||
|
||||
CC_NAME
|
||||
Compiler name, determines which "cc-*.mak" to use.
|
||||
|
||||
TARGET_NAME
|
||||
Determines suffix to be added to output files (for example,
|
||||
"libpjsip-i386-linux-gcc.a"). The value normally is equal to
|
||||
$(MACHINE_NAME)-$(OS_NAME)-$(CC_NAME), but it can contain any value.
|
||||
|
||||
CROSS_COMPILE
|
||||
Determine the prefix to be applied when invoking build tools (for
|
||||
example, "powerpc-rtems-"). The default is empty.
|
||||
|
||||
|
||||
At present, the configure script CAN NOT be used for configuring cross
|
||||
compilation. For cross compiling, you must create the "build.mak" file
|
||||
manually.
|
||||
|
||||
|
||||
2. Supported Hosts and Targets
|
||||
|
||||
The number of supported hosts and targets will (hopefully) increase over time.
|
||||
See "build/" subdirectory for list of supported machines, OSes, hosts, and
|
||||
compilers.
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
#
|
||||
# This file contains all possible values for the build.mak. Select
|
||||
# the appropriate settings, and put it in build.mak.
|
||||
#
|
||||
# (Just in case "./configure" fails to detect the appropriate values).
|
||||
#
|
||||
# Build configurations:
|
||||
#
|
||||
# MACHINE_NAME values:
|
||||
# - i386 (generic x86)
|
||||
# - sparc
|
||||
# - alpha
|
||||
#
|
||||
# OS_NAME values:
|
||||
# - win32 (generic windows)
|
||||
# - linux
|
||||
# - sunos
|
||||
#
|
||||
# CC_NAME values:
|
||||
# - gcc
|
||||
# - msvc
|
||||
#
|
||||
# HOST_NAME values:
|
||||
# - win32 (Windows command line)
|
||||
# - mingw (Windows, mingw)
|
||||
# - unix
|
||||
#
|
||||
|
||||
#
|
||||
# PalmOS 6 cross-compile, cygwin
|
||||
#
|
||||
#export MACHINE_NAME := m68k
|
||||
#export OS_NAME := palmos
|
||||
#export CC_NAME := gcc
|
||||
#export HOST_NAME := mingw
|
||||
|
||||
#
|
||||
# Win32, mingw
|
||||
#
|
||||
#export MACHINE_NAME := i386
|
||||
#export OS_NAME := win32
|
||||
#export CC_NAME := gcc
|
||||
#export HOST_NAME := mingw
|
||||
|
||||
#
|
||||
# Linux i386, gcc
|
||||
#
|
||||
export MACHINE_NAME := i386
|
||||
export OS_NAME := linux
|
||||
export CC_NAME := gcc
|
||||
export HOST_NAME := unix
|
||||
|
||||
#
|
||||
# Linux KERNEL i386, gcc
|
||||
#
|
||||
#export MACHINE_NAME := i386
|
||||
#export OS_NAME := linux-kernel
|
||||
#export CC_NAME := gcc
|
||||
#export HOST_NAME := unix
|
||||
#export PJPROJECT_DIR := /usr/src/pjproject-0.3
|
||||
##export KERNEL_DIR = /usr/src/linux
|
||||
#export KERNEL_DIR = /usr/src/uml/linux
|
||||
#export KERNEL_ARCH = ARCH=um
|
||||
|
||||
#
|
||||
# SunOS, sparc, gcc
|
||||
#
|
||||
#export MACHINE_NAME := sparc
|
||||
#export OS_NAME := sunos
|
||||
#export CC_NAME := gcc
|
||||
#export HOST_NAME := unix
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
export CC = $(CROSS_COMPILE)gcc -c
|
||||
export AR = $(CROSS_COMPILE)ar r
|
||||
export AR = $(CROSS_COMPILE)ar rv
|
||||
export LD = $(CROSS_COMPILE)gcc
|
||||
export LDOUT = -o
|
||||
export RANLIB = $(CROSS_COMPILE)ranlib
|
||||
|
|
|
@ -2,7 +2,7 @@ export HOST_MV := mv
|
|||
export HOST_RM := rm -f @@
|
||||
export HOST_RMR := rm -rf @@
|
||||
export HOST_RMDIR := rm -rf @@
|
||||
export HOST_MKDIR := mkdir @@
|
||||
export HOST_MKDIR := mkdir -p @@
|
||||
export HOST_EXE :=
|
||||
export HOST_PSEP := /
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# PowerPC MPC860 specific.
|
||||
# It's a PowerPC without floating point support.
|
||||
#
|
||||
export M_CFLAGS := $(CC_DEF)PJ_M_POWERPC=1 $(CC_DEF)PJ_HAS_FLOATING_POINT=0 -mcpu=860
|
||||
export M_CXXFLAGS :=
|
||||
export M_LDFLAGS := -mcpu=860
|
||||
export M_SOURCES :=
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# Global OS specific configurations for RTEMS OS.
|
||||
#
|
||||
# Thanks Zetron, Inc and Phil Torre <ptorre@zetron.com> for donating PJLIB
|
||||
# port to RTEMS.
|
||||
#
|
||||
export RTEMS_DEBUG := -ggdb3 -DRTEMS_DEBUG -DDEBUG -qrtems_debug
|
||||
|
||||
export OS_CFLAGS := $(CC_DEF)PJ_RTEMS=1 \
|
||||
-B$(RTEMS_LIBRARY_PATH)/lib/ -specs bsp_specs -qrtems
|
||||
|
||||
export OS_CXXFLAGS :=
|
||||
|
||||
export OS_LDFLAGS := -B$(RTEMS_LIBRARY_PATH)/lib/ -specs bsp_specs -qrtems
|
||||
|
||||
export OS_SOURCES :=
|
||||
|
|
@ -154,7 +154,7 @@ depend:
|
|||
for F in $(FULL_SRCS); do \
|
||||
if test -f $$F; then \
|
||||
echo "$(OBJDIR)/" | tr -d '\n' >> $(DEP_FILE); \
|
||||
if gcc -M $(DEPFLAGS) $$F | sed '/^#/d' >> $(DEP_FILE); then \
|
||||
if $(CC_NAME) -M $(DEPFLAGS) $$F | sed '/^#/d' >> $(DEP_FILE); then \
|
||||
true; \
|
||||
else \
|
||||
echo 'err:' >> $(DEP_FILE); \
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Detect machine
|
||||
# Detect machine, unless the choice has been made already.
|
||||
#
|
||||
MACHINE=`uname -p`
|
||||
if echo $MACHINE | grep unknown > /dev/null; then
|
||||
MACHINE=`uname -m`
|
||||
fi;
|
||||
if [ "$MACHINE" = "" ]; then
|
||||
MACHINE=`uname -m`
|
||||
fi
|
||||
|
||||
if echo $MACHINE | grep sparc > /dev/null; then
|
||||
if echo $MACHINE | grep sun4u > /dev/null; then
|
||||
MACHINE_NAME=sparc
|
||||
elif echo $MACHINE | grep i.86 > /dev/null; then
|
||||
MACHINE_NAME=i386
|
||||
|
@ -17,14 +16,17 @@ elif echo $MACHINE | grep alpha > /dev/null; then
|
|||
elif echo $MACHINE | grep powerpc > /dev/null; then
|
||||
MACHINE_NAME=powerpc
|
||||
else
|
||||
echo "Unable to detect processor type ('uname -p' == '$MACHINE')"
|
||||
echo "Unable to detect processor type ('uname -m' == '$MACHINE')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# Detect OS and host
|
||||
# Detect OS and host, unless the choice has been made already
|
||||
#
|
||||
SYSTEM=`uname -s`
|
||||
if [ "$SYSTEM" = "" ]; then
|
||||
SYSTEM=`uname -s`
|
||||
fi
|
||||
|
||||
|
||||
if echo $SYSTEM | grep -i sunos > /dev/null; then
|
||||
OS_NAME=sunos
|
||||
|
@ -53,25 +55,33 @@ elif echo $SYSTEM | grep -i cygwin > /dev/null; then
|
|||
elif echo $SYSTEM | grep -i darwin > /dev/null; then
|
||||
OS_NAME=darwinos
|
||||
HOST_NAME=unix
|
||||
elif echo $SYSTEM | grep -i rtems > /dev/null; then
|
||||
OS_NAME=rtems
|
||||
HOST_NAME=unix
|
||||
else
|
||||
echo "Unable to detect system type ('uname -s' == '$SYSTEM')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# Detect gcc
|
||||
# Detect gcc, unless it has been chosen already
|
||||
#
|
||||
if gcc --version 2>&1 > /dev/null; then
|
||||
CC_NAME=gcc
|
||||
else
|
||||
echo "Unable to find gcc"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$CC_NAME" = "" ]; then
|
||||
if gcc --version 2>&1 > /dev/null; then
|
||||
CC_NAME=gcc
|
||||
else
|
||||
echo "Unable to find gcc"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# TARGET
|
||||
# Specify TARGET_NAME, if not already choosen.
|
||||
#
|
||||
TARGET_NAME=$MACHINE_NAME-$OS_NAME-$CC_NAME
|
||||
if [ "$TARGET_NAME" = "" ]; then
|
||||
TARGET_NAME=$MACHINE_NAME-$OS_NAME-$CC_NAME
|
||||
fi
|
||||
|
||||
|
||||
if test -f build.mak; then
|
||||
|
@ -85,6 +95,7 @@ echo " OS_NAME = $OS_NAME"
|
|||
echo " HOST_NAME = $HOST_NAME"
|
||||
echo " CC_NAME = $CC_NAME"
|
||||
echo " TARGET_NAME = $TARGET_NAME"
|
||||
echo " CROSS_COMPILE= $CROSS_COMPILE"
|
||||
echo " LINUX_POLL = $LINUX_POLL"
|
||||
|
||||
echo "# Auto-generated build.mak" > build.mak
|
||||
|
@ -93,6 +104,7 @@ echo "export OS_NAME := $OS_NAME" >> build.mak
|
|||
echo "export HOST_NAME := $HOST_NAME" >> build.mak
|
||||
echo "export CC_NAME := $CC_NAME" >> build.mak
|
||||
echo "export TARGET_NAME := $TARGET_NAME" >> build.mak
|
||||
echo "export CROSS_COMPILE := $CROSS_COMPILE" >> build.mak
|
||||
echo "export LINUX_POLL := $LINUX_POLL" >> build.mak
|
||||
|
||||
touch user.mak
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# PJLIB OS specific configuration for RTEMS
|
||||
#
|
||||
# Thanks Zetron, Inc. and Phil Torre <ptorre@zetron.com> for donating PJLIB
|
||||
# port to RTEMS.
|
||||
#
|
||||
|
||||
#
|
||||
# PJLIB_OBJS specified here are object files to be included in PJLIB
|
||||
# (the library) for this specific operating system. Object files common
|
||||
# to all operating systems should go in Makefile instead.
|
||||
#
|
||||
export PJLIB_OBJS += addr_resolv_sock.o guid_simple.o \
|
||||
log_writer_stdout.o os_core_unix.o \
|
||||
os_error_unix.o os_time_unix.o \
|
||||
os_timestamp_common.o os_timestamp_posix.o \
|
||||
pool_policy_malloc.o sock_bsd.o sock_select.o
|
||||
|
||||
export PJLIB_OBJS += ioqueue_select.o
|
||||
export PJLIB_OBJS += file_access_unistd.o file_io_ansi.o
|
||||
|
||||
#
|
||||
# TEST_OBJS are operating system specific object files to be included in
|
||||
# the test application.
|
||||
#
|
||||
export TEST_OBJS += main_rtems.o
|
||||
|
||||
#
|
||||
# RTEMS_LIBRARY_PATH points to the installed RTEMS libraries for the
|
||||
# desired target. pjlib-test can't link without this.
|
||||
#
|
||||
export RTEMS_LIBRARY_PATH := $(RTEMS_LIBRARY_PATH)
|
||||
|
||||
#
|
||||
# Additional LDFLAGS for pjlib-test
|
||||
#
|
||||
export TEST_LDFLAGS +=
|
||||
|
||||
#
|
||||
# TARGETS are make targets in the Makefile, to be executed for this given
|
||||
# operating system.
|
||||
#
|
||||
export TARGETS = pjlib pjlib-test
|
||||
|
||||
|
||||
|
|
@ -94,6 +94,10 @@
|
|||
* Socket related
|
||||
*/
|
||||
typedef int socklen_t;
|
||||
|
||||
/* Set 1 if native sockaddr_in has sin_len member.
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SOCKADDR_HAS_LEN 1
|
||||
|
||||
/*
|
||||
|
@ -105,6 +109,32 @@ typedef int socklen_t;
|
|||
*/
|
||||
#define PJ_IOQUEUE_MAX_HANDLES 1024
|
||||
|
||||
/**
|
||||
* If this macro is set, it tells select I/O Queue that select() needs to
|
||||
* be given correct value of nfds (i.e. largest fd + 1). This requires
|
||||
* select ioqueue to re-scan the descriptors on each registration and
|
||||
* unregistration.
|
||||
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
|
||||
* nfds argument when calling select().
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SELECT_NEEDS_NFDS 0
|
||||
|
||||
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
|
||||
#define PJ_EMULATE_RWMUTEX 0
|
||||
|
||||
/* If 1, pj_thread_create() should enforce the stack size when creating
|
||||
* threads.
|
||||
* Default: 0 (let OS decide the thread's stack size).
|
||||
*/
|
||||
#define PJ_THREAD_SET_STACK_SIZE 0
|
||||
|
||||
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
|
||||
* Default: 0 (let OS allocate memory for thread's stack).
|
||||
*/
|
||||
#define PJ_THREAD_ALLOCATE_STACK 0
|
||||
|
||||
|
||||
#endif /* __PJ_COMPAT_OS_DARWINOS_H__ */
|
||||
|
||||
|
|
|
@ -54,8 +54,24 @@
|
|||
#define PJ_HAS_WINSOCK2_H 0
|
||||
|
||||
#define PJ_SOCK_HAS_INET_ATON 1
|
||||
|
||||
/* Set 1 if native sockaddr_in has sin_len member.
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SOCKADDR_HAS_LEN 0
|
||||
|
||||
/**
|
||||
* If this macro is set, it tells select I/O Queue that select() needs to
|
||||
* be given correct value of nfds (i.e. largest fd + 1). This requires
|
||||
* select ioqueue to re-scan the descriptors on each registration and
|
||||
* unregistration.
|
||||
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
|
||||
* nfds argument when calling select().
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SELECT_NEEDS_NFDS 0
|
||||
|
||||
/* Is errno a good way to retrieve OS errors?
|
||||
*/
|
||||
#define PJ_HAS_ERRNO_VAR 1
|
||||
|
@ -89,5 +105,21 @@
|
|||
|
||||
#define PJ_ATOMIC_VALUE_TYPE long
|
||||
|
||||
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
|
||||
#define PJ_EMULATE_RWMUTEX 0
|
||||
|
||||
/* If 1, pj_thread_create() should enforce the stack size when creating
|
||||
* threads.
|
||||
* Default: 0 (let OS decide the thread's stack size).
|
||||
*/
|
||||
#define PJ_THREAD_SET_STACK_SIZE 0
|
||||
|
||||
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
|
||||
* Default: 0 (let OS allocate memory for thread's stack).
|
||||
*/
|
||||
#define PJ_THREAD_ALLOCATE_STACK 0
|
||||
|
||||
|
||||
|
||||
#endif /* __PJ_COMPAT_OS_LINUX_H__ */
|
||||
|
||||
|
|
|
@ -54,6 +54,10 @@
|
|||
#define PJ_HAS_WINSOCK2_H 0
|
||||
|
||||
#define PJ_SOCK_HAS_INET_ATON 0
|
||||
|
||||
/* Set 1 if native sockaddr_in has sin_len member.
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SOCKADDR_HAS_LEN 0
|
||||
|
||||
/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
|
||||
|
@ -61,6 +65,18 @@
|
|||
*/
|
||||
#define PJ_HAS_SO_ERROR 1
|
||||
|
||||
/**
|
||||
* If this macro is set, it tells select I/O Queue that select() needs to
|
||||
* be given correct value of nfds (i.e. largest fd + 1). This requires
|
||||
* select ioqueue to re-scan the descriptors on each registration and
|
||||
* unregistration.
|
||||
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
|
||||
* nfds argument when calling select().
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SELECT_NEEDS_NFDS 0
|
||||
|
||||
/* This value specifies the value set in errno by the OS when a non-blocking
|
||||
* socket recv() can not return immediate daata.
|
||||
*/
|
||||
|
@ -104,5 +120,21 @@
|
|||
#define PJ_ATOMIC_VALUE_TYPE int
|
||||
#define PJ_THREAD_DESC_SIZE 128
|
||||
|
||||
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
|
||||
#define PJ_EMULATE_RWMUTEX 0
|
||||
|
||||
/* If 1, pj_thread_create() should enforce the stack size when creating
|
||||
* threads.
|
||||
* Default: 0 (let OS decide the thread's stack size).
|
||||
*/
|
||||
#define PJ_THREAD_SET_STACK_SIZE 0
|
||||
|
||||
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
|
||||
* Default: 0 (let OS allocate memory for thread's stack).
|
||||
*/
|
||||
#define PJ_THREAD_ALLOCATE_STACK 0
|
||||
|
||||
|
||||
|
||||
#endif /* __PJ_COMPAT_OS_LINUX_KERNEL_H__ */
|
||||
|
||||
|
|
|
@ -52,8 +52,24 @@
|
|||
#define PJ_HAS_WINSOCK2_H 0
|
||||
|
||||
#define PJ_SOCK_HAS_INET_ATON 0
|
||||
|
||||
/* Set 1 if native sockaddr_in has sin_len member.
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SOCKADDR_HAS_LEN 0
|
||||
|
||||
/**
|
||||
* If this macro is set, it tells select I/O Queue that select() needs to
|
||||
* be given correct value of nfds (i.e. largest fd + 1). This requires
|
||||
* select ioqueue to re-scan the descriptors on each registration and
|
||||
* unregistration.
|
||||
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
|
||||
* nfds argument when calling select().
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SELECT_NEEDS_NFDS 0
|
||||
|
||||
/* Is errno a good way to retrieve OS errors?
|
||||
*/
|
||||
#define PJ_HAS_ERRNO_VAR 0
|
||||
|
@ -83,4 +99,20 @@
|
|||
# define PJ_OS_HAS_CHECK_STACK 0
|
||||
#define PJ_NATIVE_STRING_IS_UNICODE 0
|
||||
|
||||
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
|
||||
#define PJ_EMULATE_RWMUTEX 1
|
||||
|
||||
/* If 1, pj_thread_create() should enforce the stack size when creating
|
||||
* threads.
|
||||
* Default: 0 (let OS decide the thread's stack size).
|
||||
*/
|
||||
#define PJ_THREAD_SET_STACK_SIZE 0
|
||||
|
||||
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
|
||||
* Default: 0 (let OS allocate memory for thread's stack).
|
||||
*/
|
||||
#define PJ_THREAD_ALLOCATE_STACK 0
|
||||
|
||||
|
||||
#endif /* __PJ_COMPAT_OS_PALMOS_H__ */
|
||||
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/* $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.
|
||||
*/
|
||||
|
||||
#ifndef __PJ_COMPAT_OS_RTEMS_H__
|
||||
#define __PJ_COMPAT_OS_RTEMS_H__
|
||||
|
||||
/**
|
||||
* @file os_linux.h
|
||||
* @brief Describes Linux operating system specifics.
|
||||
*/
|
||||
|
||||
#define PJ_OS_NAME "rtems"
|
||||
|
||||
#define PJ_HAS_ARPA_INET_H 1
|
||||
#define PJ_HAS_ASSERT_H 1
|
||||
#define PJ_HAS_CTYPE_H 1
|
||||
#define PJ_HAS_ERRNO_H 1
|
||||
#define PJ_HAS_LINUX_SOCKET_H 0
|
||||
#define PJ_HAS_MALLOC_H 1
|
||||
#define PJ_HAS_NETDB_H 1
|
||||
#define PJ_HAS_NETINET_IN_H 1
|
||||
#define PJ_HAS_SETJMP_H 1
|
||||
#define PJ_HAS_STDARG_H 0
|
||||
#define PJ_HAS_STDDEF_H 1
|
||||
#define PJ_HAS_STDIO_H 1
|
||||
#define PJ_HAS_STDLIB_H 1
|
||||
#define PJ_HAS_STRING_H 1
|
||||
#define PJ_HAS_SYS_IOCTL_H 1
|
||||
#define PJ_HAS_SYS_SELECT_H 1
|
||||
#define PJ_HAS_SYS_SOCKET_H 1
|
||||
#define PJ_HAS_SYS_TIME_H 1
|
||||
#define PJ_HAS_SYS_TIMEB_H 1
|
||||
#define PJ_HAS_SYS_TYPES_H 1
|
||||
#define PJ_HAS_TIME_H 1
|
||||
#define PJ_HAS_UNISTD_H 1
|
||||
|
||||
#define PJ_HAS_MSWSOCK_H 0
|
||||
#define PJ_HAS_WINSOCK_H 0
|
||||
#define PJ_HAS_WINSOCK2_H 0
|
||||
|
||||
#define PJ_SOCK_HAS_INET_ATON 1
|
||||
|
||||
/* Set 1 if native sockaddr_in has sin_len member.
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SOCKADDR_HAS_LEN 1
|
||||
|
||||
/* Is errno a good way to retrieve OS errors?
|
||||
*/
|
||||
#define PJ_HAS_ERRNO_VAR 1
|
||||
|
||||
/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
|
||||
* the status of non-blocking connect() operation.
|
||||
*/
|
||||
#define PJ_HAS_SO_ERROR 1
|
||||
|
||||
/**
|
||||
* If this macro is set, it tells select I/O Queue that select() needs to
|
||||
* be given correct value of nfds (i.e. largest fd + 1). This requires
|
||||
* select ioqueue to re-scan the descriptors on each registration and
|
||||
* unregistration.
|
||||
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
|
||||
* nfds argument when calling select().
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SELECT_NEEDS_NFDS 1
|
||||
|
||||
/* This value specifies the value set in errno by the OS when a non-blocking
|
||||
* socket recv() can not return immediate daata.
|
||||
*/
|
||||
#define PJ_BLOCKING_ERROR_VAL EWOULDBLOCK
|
||||
|
||||
/* This value specifies the value set in errno by the OS when a non-blocking
|
||||
* socket connect() can not get connected immediately.
|
||||
*/
|
||||
#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
|
||||
|
||||
/* Default threading is enabled, unless it's overridden. */
|
||||
#ifndef PJ_HAS_THREADS
|
||||
# define PJ_HAS_THREADS (1)
|
||||
#endif
|
||||
|
||||
#define PJ_HAS_HIGH_RES_TIMER 1
|
||||
#define PJ_HAS_MALLOC 1
|
||||
#ifndef PJ_OS_HAS_CHECK_STACK
|
||||
# define PJ_OS_HAS_CHECK_STACK 0
|
||||
#endif
|
||||
#define PJ_NATIVE_STRING_IS_UNICODE 0
|
||||
|
||||
#define PJ_ATOMIC_VALUE_TYPE int
|
||||
|
||||
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
|
||||
#define PJ_EMULATE_RWMUTEX 1
|
||||
|
||||
/* Missing socklen_t */
|
||||
typedef int socklen_t;
|
||||
|
||||
/* If 1, pj_thread_create() should enforce the stack size when creating
|
||||
* threads.
|
||||
* Default: 0 (let OS decide the thread's stack size).
|
||||
*/
|
||||
#define PJ_THREAD_SET_STACK_SIZE 1
|
||||
|
||||
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
|
||||
* Default: 0 (let OS allocate memory for thread's stack).
|
||||
*/
|
||||
#define PJ_THREAD_ALLOCATE_STACK 1
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __PJ_COMPAT_OS_RTEMS_H__ */
|
||||
|
|
@ -54,6 +54,10 @@
|
|||
#define PJ_HAS_WINSOCK2_H 0
|
||||
|
||||
#define PJ_SOCK_HAS_INET_ATON 0
|
||||
|
||||
/* Set 1 if native sockaddr_in has sin_len member.
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SOCKADDR_HAS_LEN 0
|
||||
|
||||
/* Is errno a good way to retrieve OS errors?
|
||||
|
@ -75,6 +79,18 @@
|
|||
*/
|
||||
#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
|
||||
|
||||
/**
|
||||
* If this macro is set, it tells select I/O Queue that select() needs to
|
||||
* be given correct value of nfds (i.e. largest fd + 1). This requires
|
||||
* select ioqueue to re-scan the descriptors on each registration and
|
||||
* unregistration.
|
||||
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
|
||||
* nfds argument when calling select().
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SELECT_NEEDS_NFDS 0
|
||||
|
||||
/* Default threading is enabled, unless it's overridden. */
|
||||
#ifndef PJ_HAS_THREADS
|
||||
# define PJ_HAS_THREADS (1)
|
||||
|
@ -92,5 +108,21 @@
|
|||
/* Get BSD related identifers in Sun's include files */
|
||||
#define BSD_COMP
|
||||
|
||||
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
|
||||
#define PJ_EMULATE_RWMUTEX 0
|
||||
|
||||
/* If 1, pj_thread_create() should enforce the stack size when creating
|
||||
* threads.
|
||||
* Default: 0 (let OS decide the thread's stack size).
|
||||
*/
|
||||
#define PJ_THREAD_SET_STACK_SIZE 0
|
||||
|
||||
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
|
||||
* Default: 0 (let OS allocate memory for thread's stack).
|
||||
*/
|
||||
#define PJ_THREAD_ALLOCATE_STACK 0
|
||||
|
||||
|
||||
|
||||
#endif /* __PJ_COMPAT_OS_SUNOS_H__ */
|
||||
|
||||
|
|
|
@ -60,6 +60,10 @@
|
|||
#define PJ_HAS_WINSOCK2_H 1
|
||||
|
||||
#define PJ_SOCK_HAS_INET_ATON 0
|
||||
|
||||
/* Set 1 if native sockaddr_in has sin_len member.
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SOCKADDR_HAS_LEN 0
|
||||
|
||||
/* Is errno a good way to retrieve OS errors? (No)
|
||||
|
@ -81,6 +85,18 @@
|
|||
*/
|
||||
#define PJ_BLOCKING_CONNECT_ERROR_VAL WSAEWOULDBLOCK
|
||||
|
||||
/**
|
||||
* If this macro is set, it tells select I/O Queue that select() needs to
|
||||
* be given correct value of nfds (i.e. largest fd + 1). This requires
|
||||
* select ioqueue to re-scan the descriptors on each registration and
|
||||
* unregistration.
|
||||
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
|
||||
* nfds argument when calling select().
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SELECT_NEEDS_NFDS 0
|
||||
|
||||
/* Default threading is enabled, unless it's overridden. */
|
||||
#ifndef PJ_HAS_THREADS
|
||||
# define PJ_HAS_THREADS (1)
|
||||
|
@ -95,4 +111,20 @@
|
|||
|
||||
#define PJ_ATOMIC_VALUE_TYPE long
|
||||
|
||||
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
|
||||
#define PJ_EMULATE_RWMUTEX 1
|
||||
|
||||
/* If 1, pj_thread_create() should enforce the stack size when creating
|
||||
* threads.
|
||||
* Default: 0 (let OS decide the thread's stack size).
|
||||
*/
|
||||
#define PJ_THREAD_SET_STACK_SIZE 0
|
||||
|
||||
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
|
||||
* Default: 0 (let OS allocate memory for thread's stack).
|
||||
*/
|
||||
#define PJ_THREAD_ALLOCATE_STACK 0
|
||||
|
||||
|
||||
#endif /* __PJ_COMPAT_OS_WIN32_H__ */
|
||||
|
||||
|
|
|
@ -58,6 +58,10 @@
|
|||
#define PJ_HAS_WINSOCK2_H 1
|
||||
|
||||
#define PJ_SOCK_HAS_INET_ATON 0
|
||||
|
||||
/* Set 1 if native sockaddr_in has sin_len member.
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SOCKADDR_HAS_LEN 0
|
||||
|
||||
/* Is errno a good way to retrieve OS errors? (no)
|
||||
|
@ -79,6 +83,18 @@
|
|||
*/
|
||||
#define PJ_BLOCKING_CONNECT_ERROR_VAL WSAEWOULDBLOCK
|
||||
|
||||
/**
|
||||
* If this macro is set, it tells select I/O Queue that select() needs to
|
||||
* be given correct value of nfds (i.e. largest fd + 1). This requires
|
||||
* select ioqueue to re-scan the descriptors on each registration and
|
||||
* unregistration.
|
||||
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
|
||||
* nfds argument when calling select().
|
||||
*
|
||||
* Default: 0
|
||||
*/
|
||||
#define PJ_SELECT_NEEDS_NFDS 0
|
||||
|
||||
/* Default threading is enabled, unless it's overridden. */
|
||||
#ifndef PJ_HAS_THREADS
|
||||
# define PJ_HAS_THREADS (1)
|
||||
|
@ -102,5 +118,20 @@
|
|||
/* Native string is Unicode. */
|
||||
#define PJ_NATIVE_STRING_IS_UNICODE 1
|
||||
|
||||
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
|
||||
#define PJ_EMULATE_RWMUTEX 1
|
||||
|
||||
/* If 1, pj_thread_create() should enforce the stack size when creating
|
||||
* threads.
|
||||
* Default: 0 (let OS decide the thread's stack size).
|
||||
*/
|
||||
#define PJ_THREAD_SET_STACK_SIZE 0
|
||||
|
||||
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
|
||||
* Default: 0 (let OS allocate memory for thread's stack).
|
||||
*/
|
||||
#define PJ_THREAD_ALLOCATE_STACK 0
|
||||
|
||||
|
||||
#endif /* __PJ_COMPAT_OS_WIN32_WINCE_H__ */
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
# include <pj/compat/os_sunos.h>
|
||||
#elif defined(PJ_DARWINOS) && PJ_DARWINOS!=0
|
||||
# include <pj/compat/os_darwinos.h>
|
||||
#elif defined(PJ_RTEMS) && PJ_RTEMS!=0
|
||||
# include <pj/compat/os_rtems.h>
|
||||
#else
|
||||
# error "Please specify target os."
|
||||
#endif
|
||||
|
@ -222,6 +224,17 @@
|
|||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Specify this as \a stack_size argument in #pj_thread_create() to specify
|
||||
* that thread should use default stack size for the current platform.
|
||||
*
|
||||
* Default: 8192
|
||||
*/
|
||||
#ifndef PJ_THREAD_DEFAULT_STACK_SIZE
|
||||
# define PJ_THREAD_DEFAULT_STACK_SIZE 8192
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Do we have alternate pool implementation?
|
||||
*
|
||||
|
@ -556,7 +569,17 @@
|
|||
# error "PJ_IS_BIG_ENDIAN is not defined!"
|
||||
#endif
|
||||
|
||||
#if !defined(PJ_EMULATE_RWMUTEX)
|
||||
# error "PJ_EMULATE_RWMUTEX should be defined in compat/os_xx.h"
|
||||
#endif
|
||||
|
||||
#if !defined(PJ_THREAD_SET_STACK_SIZE)
|
||||
# error "PJ_THREAD_SET_STACK_SIZE should be defined in compat/os_xx.h"
|
||||
#endif
|
||||
|
||||
#if !defined(PJ_THREAD_ALLOCATE_STACK)
|
||||
# error "PJ_THREAD_ALLOCATE_STACK should be defined in compat/os_xx.h"
|
||||
#endif
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
||||
|
|
|
@ -58,12 +58,6 @@ typedef enum pj_thread_create_flags
|
|||
} pj_thread_create_flags;
|
||||
|
||||
|
||||
/**
|
||||
* Specify this as \a stack_size argument in #pj_thread_create() to specify
|
||||
* that thread should use default stack size for the current platform.
|
||||
*/
|
||||
#define PJ_THREAD_DEFAULT_STACK_SIZE 0
|
||||
|
||||
/**
|
||||
* Type of thread entry function.
|
||||
*/
|
||||
|
@ -161,12 +155,13 @@ PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
|
|||
PJ_DECL(pj_thread_t*) pj_thread_this(void);
|
||||
|
||||
/**
|
||||
* Join thread.
|
||||
* This function will block the caller thread until the specified thread exits.
|
||||
* Join thread, and block the caller thread until the specified thread exits.
|
||||
* If the specified thread has already been dead, or it does not exist,
|
||||
* the function will return immediately with successfull status.
|
||||
*
|
||||
* @param thread The thread handle.
|
||||
*
|
||||
* @return zero on success.
|
||||
* @return PJ_SUCCESS on success.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
|
||||
|
||||
|
|
|
@ -49,20 +49,21 @@ struct pj_hash_table_t
|
|||
|
||||
|
||||
|
||||
PJ_DEF(pj_uint32_t) pj_hash_calc(pj_uint32_t hash, const void *key, unsigned keylen)
|
||||
PJ_DEF(pj_uint32_t) pj_hash_calc(pj_uint32_t hash, const void *key,
|
||||
unsigned keylen)
|
||||
{
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (keylen==PJ_HASH_KEY_STRING) {
|
||||
const unsigned char *p = key;
|
||||
for ( ; *p; ++p ) {
|
||||
hash = hash * PJ_HASH_MULTIPLIER + *p;
|
||||
hash = (hash * PJ_HASH_MULTIPLIER) + *p;
|
||||
}
|
||||
} else {
|
||||
const unsigned char *p = key,
|
||||
*end = p + keylen;
|
||||
for ( ; p!=end; ++p) {
|
||||
hash = hash * PJ_HASH_MULTIPLIER + *p;
|
||||
hash = (hash * PJ_HASH_MULTIPLIER) + *p;
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
|
|
|
@ -237,7 +237,7 @@ void ioqueue_dispatch_write_event(pj_ioqueue_t *ioqueue, pj_ioqueue_key_t *h)
|
|||
socklen_t addrlen = sizeof(addr);
|
||||
|
||||
gp_rc = getpeername(h->fd, (struct sockaddr*)&addr, &addrlen);
|
||||
bytes_transfered = gp_rc;
|
||||
bytes_transfered = (gp_rc < 0) ? gp_rc : -gp_rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -93,6 +93,12 @@ PJ_DECL(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp);
|
|||
*/
|
||||
#define VALIDATE_FD_SET 0
|
||||
|
||||
#if 0
|
||||
# define TRACE__(args) PJ_LOG(3,args)
|
||||
#else
|
||||
# define TRACE__(args)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This describes each key.
|
||||
*/
|
||||
|
@ -108,8 +114,9 @@ struct pj_ioqueue_t
|
|||
{
|
||||
DECLARE_COMMON_IOQUEUE
|
||||
|
||||
unsigned max, count;
|
||||
pj_ioqueue_key_t active_list;
|
||||
unsigned max, count; /* Max and current key count */
|
||||
int nfds; /* The largest fd value (for select)*/
|
||||
pj_ioqueue_key_t active_list; /* List of active keys. */
|
||||
pj_fd_set_t rfdset;
|
||||
pj_fd_set_t wfdset;
|
||||
#if PJ_HAS_TCP
|
||||
|
@ -136,6 +143,32 @@ PJ_DEF(const char*) pj_ioqueue_name(void)
|
|||
return "select";
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the socket descriptor sets for the largest descriptor.
|
||||
* This value is needed by select().
|
||||
*/
|
||||
#if defined(PJ_SELECT_NEEDS_NFDS) && PJ_SELECT_NEEDS_NFDS!=0
|
||||
static void rescan_fdset(pj_ioqueue_t *ioqueue)
|
||||
{
|
||||
pj_ioqueue_key_t *key = ioqueue->active_list.next;
|
||||
int max = 0;
|
||||
|
||||
while (key != &ioqueue->active_list) {
|
||||
if (key->fd > max)
|
||||
max = key->fd;
|
||||
key = key->next;
|
||||
}
|
||||
|
||||
ioqueue->nfds = max;
|
||||
}
|
||||
#else
|
||||
static void rescan_fdset(pj_ioqueue_t *ioqueue)
|
||||
{
|
||||
ioqueue->nfds = FD_SETSIZE-1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* pj_ioqueue_create()
|
||||
*
|
||||
|
@ -172,6 +205,8 @@ PJ_DEF(pj_status_t) pj_ioqueue_create( pj_pool_t *pool,
|
|||
#endif
|
||||
pj_list_init(&ioqueue->active_list);
|
||||
|
||||
rescan_fdset(ioqueue);
|
||||
|
||||
#if PJ_IOQUEUE_HAS_SAFE_UNREG
|
||||
/* When safe unregistration is used (the default), we pre-create
|
||||
* all keys and put them in the free list.
|
||||
|
@ -332,6 +367,9 @@ PJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,
|
|||
pj_list_insert_before(&ioqueue->active_list, key);
|
||||
++ioqueue->count;
|
||||
|
||||
/* Rescan fdset to get max descriptor */
|
||||
rescan_fdset(ioqueue);
|
||||
|
||||
on_return:
|
||||
/* On error, socket may be left in non-blocking mode. */
|
||||
*p_key = key;
|
||||
|
@ -368,6 +406,8 @@ static void decrement_counter(pj_ioqueue_key_t *key)
|
|||
pj_lock_acquire(key->ioqueue->lock);
|
||||
pj_list_erase(key);
|
||||
pj_list_push_back(&key->ioqueue->closing_list, key);
|
||||
/* Rescan fdset to get max descriptor */
|
||||
rescan_fdset(key->ioqueue);
|
||||
pj_lock_release(key->ioqueue->lock);
|
||||
}
|
||||
pj_mutex_unlock(key->ioqueue->ref_cnt_mutex);
|
||||
|
@ -611,6 +651,7 @@ PJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioqueue, const pj_time_val *timeout)
|
|||
scan_closing_keys(ioqueue);
|
||||
#endif
|
||||
pj_lock_release(ioqueue->lock);
|
||||
TRACE__((THIS_FILE, " poll: no fd is set"));
|
||||
if (timeout)
|
||||
pj_thread_sleep(PJ_TIME_VAL_MSEC(*timeout));
|
||||
return 0;
|
||||
|
@ -632,7 +673,8 @@ PJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioqueue, const pj_time_val *timeout)
|
|||
/* Unlock ioqueue before select(). */
|
||||
pj_lock_release(ioqueue->lock);
|
||||
|
||||
count = pj_sock_select(FD_SETSIZE, &rfdset, &wfdset, &xfdset, timeout);
|
||||
count = pj_sock_select(ioqueue->nfds+1, &rfdset, &wfdset, &xfdset,
|
||||
timeout);
|
||||
|
||||
if (count <= 0)
|
||||
return -pj_get_netos_error();
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* Contributors:
|
||||
* - Thanks for Zetron, Inc. (Phil Torre, ptorre@zetron.com) for donating
|
||||
* the RTEMS port.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <pj/os.h>
|
||||
#include <pj/assert.h>
|
||||
|
@ -153,7 +158,7 @@ PJ_DEF(pj_status_t) pj_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
PJ_LOG(4,(THIS_FILE, "pjlib %s for Unix initialized",
|
||||
PJ_LOG(4,(THIS_FILE, "pjlib %s for POSIX initialized",
|
||||
PJ_VERSION));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
|
@ -196,6 +201,8 @@ PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,
|
|||
// has been deleted by application.
|
||||
//*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id);
|
||||
//return PJ_SUCCESS;
|
||||
PJ_LOG(4,(THIS_FILE, "Info: possibly re-registering existing "
|
||||
"thread"));
|
||||
}
|
||||
|
||||
/* Initialize and set the thread entry. */
|
||||
|
@ -281,6 +288,7 @@ static void *thread_main(void *param)
|
|||
|
||||
/* Done. */
|
||||
PJ_LOG(6,(rec->obj_name, "Thread quitting"));
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
@ -298,15 +306,18 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
|
|||
{
|
||||
#if PJ_HAS_THREADS
|
||||
pj_thread_t *rec;
|
||||
pthread_attr_t thread_attr;
|
||||
void *stack_addr;
|
||||
int rc;
|
||||
|
||||
PJ_UNUSED_ARG(stack_addr);
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
PJ_ASSERT_RETURN(pool && proc && ptr_thread, PJ_EINVAL);
|
||||
|
||||
/* Create thread record and assign name for the thread */
|
||||
rec = (struct pj_thread_t*) pj_pool_zalloc(pool, sizeof(pj_thread_t));
|
||||
if (!rec)
|
||||
return PJ_ENOMEM;
|
||||
PJ_ASSERT_RETURN(rec, PJ_ENOMEM);
|
||||
|
||||
/* Set name. */
|
||||
if (!thread_name)
|
||||
|
@ -319,32 +330,61 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
|
|||
rec->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
|
||||
}
|
||||
|
||||
/* Set default stack size */
|
||||
if (stack_size == 0)
|
||||
stack_size = PJ_THREAD_DEFAULT_STACK_SIZE;
|
||||
|
||||
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
|
||||
rec->stk_size = stack_size ? stack_size : 0xFFFFFFFFUL;
|
||||
rec->stk_size = stack_size;
|
||||
rec->stk_max_usage = 0;
|
||||
#endif
|
||||
|
||||
/* Emulate suspended thread with mutex. */
|
||||
if (flags & PJ_THREAD_SUSPENDED) {
|
||||
rc = pj_mutex_create_simple(pool, NULL, &rec->suspended_mutex);
|
||||
if (rc != PJ_SUCCESS)
|
||||
if (rc != PJ_SUCCESS) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
pj_mutex_lock(rec->suspended_mutex);
|
||||
} else {
|
||||
pj_assert(rec->suspended_mutex == NULL);
|
||||
}
|
||||
|
||||
PJ_LOG(6, (rec->obj_name, "Thread created"));
|
||||
|
||||
/* Init thread attributes */
|
||||
pthread_attr_init(&thread_attr);
|
||||
|
||||
#if defined(PJ_THREAD_SET_STACK_SIZE) && PJ_THREAD_SET_STACK_SIZE!=0
|
||||
/* Set thread's stack size */
|
||||
rc = pthread_attr_setstacksize(&thread_attr, stack_size);
|
||||
if (rc != 0)
|
||||
return PJ_RETURN_OS_ERROR(rc);
|
||||
#endif /* PJ_THREAD_SET_STACK_SIZE */
|
||||
|
||||
|
||||
#if defined(PJ_THREAD_ALLOCATE_STACK) && PJ_THREAD_ALLOCATE_STACK!=0
|
||||
/* Allocate memory for the stack */
|
||||
stack_addr = pj_pool_alloc(pool, stack_size);
|
||||
PJ_ASSERT_RETURN(stack_addr, PJ_ENOMEM);
|
||||
|
||||
rc = pthread_attr_setstackaddr(&thread_attr, stack_addr);
|
||||
if (rc != 0)
|
||||
return PJ_RETURN_OS_ERROR(rc);
|
||||
#endif /* PJ_THREAD_ALLOCATE_STACK */
|
||||
|
||||
|
||||
/* Create the thread. */
|
||||
rec->proc = proc;
|
||||
rec->arg = arg;
|
||||
rc = pthread_create( &rec->thread, NULL, thread_main, rec);
|
||||
if (rc != 0)
|
||||
rc = pthread_create( &rec->thread, &thread_attr, &thread_main, rec);
|
||||
if (rc != 0) {
|
||||
return PJ_RETURN_OS_ERROR(rc);
|
||||
}
|
||||
|
||||
*ptr_thread = rec;
|
||||
|
||||
PJ_LOG(6, (rec->obj_name, "Thread created"));
|
||||
return PJ_SUCCESS;
|
||||
#else
|
||||
pj_assert(!"Threading is disabled!");
|
||||
|
@ -423,8 +463,13 @@ PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
|
|||
|
||||
if (result == 0)
|
||||
return PJ_SUCCESS;
|
||||
else
|
||||
return PJ_RETURN_OS_ERROR(result);
|
||||
else {
|
||||
/* Calling pthread_join() on a thread that no longer exists and
|
||||
* getting back ESRCH isn't an error (in this context).
|
||||
* Thanks Phil Torre <ptorre@zetron.com>.
|
||||
*/
|
||||
return result==ESRCH ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(result);
|
||||
}
|
||||
#else
|
||||
PJ_CHECK_STACK();
|
||||
pj_assert(!"No multithreading support!");
|
||||
|
@ -437,10 +482,14 @@ PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
|
|||
*/
|
||||
PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *p)
|
||||
{
|
||||
/* This function is used to destroy thread handle in other platforms.
|
||||
* I suppose there's nothing to do here..
|
||||
*/
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
/* Destroy mutex used to suspend thread */
|
||||
if (p->suspended_mutex) {
|
||||
pj_mutex_destroy(p->suspended_mutex);
|
||||
p->suspended_mutex = NULL;
|
||||
}
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -449,8 +498,26 @@ PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *p)
|
|||
*/
|
||||
PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
|
||||
{
|
||||
/* TODO: should change this to something like PJ_OS_HAS_NANOSLEEP */
|
||||
#if defined(PJ_RTEMS) && PJ_RTEMS!=0
|
||||
enum { NANOSEC_PER_MSEC = 1000000 };
|
||||
struct timespec req;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
return usleep(msec * 1000);
|
||||
req.tv_sec = msec / 1000;
|
||||
req.tv_nsec = (msec % 1000) * NANOSEC_PER_MSEC;
|
||||
|
||||
if (nanosleep(&req, NULL) == 0)
|
||||
return PJ_SUCCESS;
|
||||
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
|
||||
#else
|
||||
PJ_CHECK_STACK();
|
||||
if (usleep(msec * 1000) == 0)
|
||||
return PJ_SUCCESS;
|
||||
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
|
||||
#endif /* PJ_RTEMS */
|
||||
}
|
||||
|
||||
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
|
||||
|
@ -513,8 +580,7 @@ PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool,
|
|||
{
|
||||
pj_status_t rc;
|
||||
pj_atomic_t *atomic_var = pj_pool_calloc(pool, 1, sizeof(pj_atomic_t));
|
||||
if (!atomic_var)
|
||||
return PJ_ENOMEM;
|
||||
PJ_ASSERT_RETURN(atomic_var, PJ_ENOMEM);
|
||||
|
||||
#if PJ_HAS_THREADS
|
||||
rc = pj_mutex_create(pool, "atm%p", PJ_MUTEX_SIMPLE, &atomic_var->mutex);
|
||||
|
@ -765,12 +831,16 @@ static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
|
|||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
pthread_mutexattr_init(&attr);
|
||||
rc = pthread_mutexattr_init(&attr);
|
||||
if (rc != 0)
|
||||
return PJ_RETURN_OS_ERROR(rc);
|
||||
|
||||
if (type == PJ_MUTEX_SIMPLE) {
|
||||
#if defined(PJ_LINUX) && PJ_LINUX!=0
|
||||
extern int pthread_mutexattr_settype(pthread_mutexattr_t*,int);
|
||||
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_FAST_NP);
|
||||
#elif defined(PJ_RTEMS) && PJ_RTEMS!=0
|
||||
/* Nothing to do, default is simple */
|
||||
#else
|
||||
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
|
||||
#endif
|
||||
|
@ -778,6 +848,13 @@ static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
|
|||
#if defined(PJ_LINUX) && PJ_LINUX!=0
|
||||
extern int pthread_mutexattr_settype(pthread_mutexattr_t*,int);
|
||||
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
#elif defined(PJ_RTEMS) && PJ_RTEMS!=0
|
||||
// Phil Torre <ptorre@zetron.com>:
|
||||
// The RTEMS implementation of POSIX mutexes doesn't include
|
||||
// pthread_mutexattr_settype(), so what follows is a hack
|
||||
// until I get RTEMS patched to support the set/get functions.
|
||||
PJ_TODO(FIX_RTEMS_RECURSIVE_MUTEX_TYPE)
|
||||
attr.recursive = 1;
|
||||
#else
|
||||
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
#endif
|
||||
|
@ -831,7 +908,7 @@ PJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool,
|
|||
PJ_ASSERT_RETURN(pool && ptr_mutex, PJ_EINVAL);
|
||||
|
||||
mutex = pj_pool_alloc(pool, sizeof(*mutex));
|
||||
if (!mutex) return PJ_ENOMEM;
|
||||
PJ_ASSERT_RETURN(mutex, PJ_ENOMEM);
|
||||
|
||||
if ((rc=init_mutex(mutex, name, type)) != PJ_SUCCESS)
|
||||
return rc;
|
||||
|
@ -1002,6 +1079,13 @@ PJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)
|
|||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* Include Read/Write mutex emulation for POSIX platforms that lack it (e.g.
|
||||
* RTEMS). Otherwise use POSIX rwlock.
|
||||
*/
|
||||
#if defined(PJ_EMULATE_RWMUTEX) && PJ_EMULATE_RWMUTEX!=0
|
||||
# include "os_rwmutex.c"
|
||||
#else
|
||||
struct pj_rwmutex_t
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
|
@ -1095,6 +1179,9 @@ PJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)
|
|||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* PJ_EMULATE_RWMUTEX */
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
|
||||
|
||||
|
@ -1113,8 +1200,8 @@ PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,
|
|||
PJ_CHECK_STACK();
|
||||
PJ_ASSERT_RETURN(pool != NULL && ptr_sem != NULL, PJ_EINVAL);
|
||||
|
||||
sem = pj_pool_alloc(pool, sizeof(*sem));
|
||||
if (!sem) return PJ_ENOMEM;
|
||||
sem = pj_pool_alloc(pool, sizeof(*sem));
|
||||
PJ_ASSERT_RETURN(sem, PJ_ENOMEM);
|
||||
|
||||
if (sem_init( &sem->sem, 0, initial) != 0)
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/* $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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note:
|
||||
*
|
||||
* DO NOT BUILD THIS FILE DIRECTLY. THIS FILE WILL BE INCLUDED BY os_core_*.c
|
||||
* WHEN MACRO PJ_EMULATE_RWMUTEX IS SET.
|
||||
*/
|
||||
|
||||
/*
|
||||
* os_rwmutex.c:
|
||||
*
|
||||
* Implementation of Read-Write mutex for platforms that lack it (e.g.
|
||||
* Win32, RTEMS).
|
||||
*/
|
||||
|
||||
|
||||
struct pj_rwmutex_t
|
||||
{
|
||||
pj_mutex_t *read_lock;
|
||||
/* write_lock must use semaphore, because write_lock may be released
|
||||
* by thread other than the thread that acquire the write_lock in the
|
||||
* first place.
|
||||
*/
|
||||
pj_sem_t *write_lock;
|
||||
pj_int32_t reader_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create reader/writer mutex.
|
||||
*
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
|
||||
pj_rwmutex_t **p_mutex)
|
||||
{
|
||||
pj_status_t status;
|
||||
pj_rwmutex_t *rwmutex;
|
||||
|
||||
PJ_ASSERT_RETURN(pool && p_mutex, PJ_EINVAL);
|
||||
|
||||
*p_mutex = NULL;
|
||||
rwmutex = pj_pool_alloc(pool, sizeof(struct pj_rwmutex_t));
|
||||
|
||||
status = pj_mutex_create_simple(pool, name, &rwmutex ->read_lock);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = pj_sem_create(pool, name, 1, 1, &rwmutex->write_lock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pj_mutex_destroy(rwmutex->read_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
rwmutex->reader_count = 0;
|
||||
*p_mutex = rwmutex;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock the mutex for reading.
|
||||
*
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex)
|
||||
{
|
||||
pj_status_t status;
|
||||
|
||||
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
|
||||
|
||||
status = pj_mutex_lock(mutex->read_lock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pj_assert(!"This pretty much is unexpected");
|
||||
return status;
|
||||
}
|
||||
|
||||
mutex->reader_count++;
|
||||
|
||||
pj_assert(mutex->reader_count < 0x7FFFFFF0L);
|
||||
|
||||
if (mutex->reader_count == 1)
|
||||
pj_sem_wait(mutex->write_lock);
|
||||
|
||||
status = pj_mutex_unlock(mutex->read_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock the mutex for writing.
|
||||
*
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex)
|
||||
{
|
||||
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
|
||||
return pj_sem_wait(mutex->write_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release read lock.
|
||||
*
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex)
|
||||
{
|
||||
pj_status_t status;
|
||||
|
||||
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
|
||||
|
||||
status = pj_mutex_lock(mutex->read_lock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pj_assert(!"This pretty much is unexpected");
|
||||
return status;
|
||||
}
|
||||
|
||||
pj_assert(mutex->reader_count >= 1);
|
||||
|
||||
--mutex->reader_count;
|
||||
if (mutex->reader_count == 0)
|
||||
pj_sem_post(mutex->write_lock);
|
||||
|
||||
status = pj_mutex_unlock(mutex->read_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release write lock.
|
||||
*
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex)
|
||||
{
|
||||
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
|
||||
pj_assert(mutex->reader_count <= 1);
|
||||
return pj_sem_post(mutex->write_lock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destroy reader/writer mutex.
|
||||
*
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)
|
||||
{
|
||||
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
|
||||
pj_mutex_destroy(mutex->read_lock);
|
||||
pj_sem_destroy(mutex->write_lock);
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
|
@ -17,23 +17,30 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <pj/os.h>
|
||||
#include <pj/errno.h>
|
||||
#include <pj/compat/time.h>
|
||||
|
||||
#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H!=0
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PJ_DEF(pj_status_t) pj_gettimeofday(pj_time_val *p_tv)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timeval the_time;
|
||||
int rc;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
p_tv->sec = tv.tv_sec;
|
||||
p_tv->msec = tv.tv_usec / 1000;
|
||||
rc = gettimeofday(&the_time, NULL);
|
||||
if (rc != 0)
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
|
||||
|
||||
p_tv->sec = the_time.tv_sec;
|
||||
p_tv->msec = the_time.tv_usec / 1000;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -173,6 +173,11 @@ PJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name,
|
|||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
/* If callback is NULL, set calback from the policy */
|
||||
if (callback == NULL)
|
||||
callback = f->policy.callback;
|
||||
|
||||
/* Allocate initial block */
|
||||
buffer = (*f->policy.block_alloc)(f, initial_size);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
/*
|
||||
* Address families conversion.
|
||||
* The values here are indexed based on pj_addr_family-0xFF00.
|
||||
* The values here are indexed based on pj_addr_family.
|
||||
*/
|
||||
const pj_uint16_t PJ_AF_UNIX = AF_UNIX;
|
||||
const pj_uint16_t PJ_AF_INET = AF_INET;
|
||||
|
@ -44,7 +44,7 @@ const pj_uint16_t PJ_AF_IRDA = 0xFFFF;
|
|||
|
||||
/*
|
||||
* Socket types conversion.
|
||||
* The values here are indexed based on pj_sock_type-0xFF00
|
||||
* The values here are indexed based on pj_sock_type
|
||||
*/
|
||||
const pj_uint16_t PJ_SOCK_STREAM = SOCK_STREAM;
|
||||
const pj_uint16_t PJ_SOCK_DGRAM = SOCK_DGRAM;
|
||||
|
@ -346,7 +346,7 @@ PJ_DEF(pj_status_t) pj_sock_bind( pj_sock_t sock,
|
|||
{
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
PJ_ASSERT_RETURN(addr && len > 0, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(addr && len >= sizeof(struct sockaddr_in), PJ_EINVAL);
|
||||
|
||||
if (bind(sock, (struct sockaddr*)addr, len) != 0)
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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_ */
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# PJMEDIA OS specific configuration for RTEMS OS target.
|
||||
#
|
||||
|
||||
export PJMEDIA_OBJS += nullsound.o
|
||||
export SOUND_OBJS = $(NULLSOUND_OBJS)
|
||||
|
|
@ -9,30 +9,31 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/*efine SIGHANDLER_T int // * signal handlers are void */
|
||||
/*efine HAS_SYSV_SIGNAL 1 // * sigs not blocked/reset? */
|
||||
//#define SIGHANDLER_T int // * signal handlers are void */
|
||||
//#define HAS_SYSV_SIGNAL 1 // * sigs not blocked/reset? */
|
||||
|
||||
#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
|
||||
/*efine HAS_LIMITS_H 1 // * /usr/include/limits.h */
|
||||
#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
|
||||
/*efine HAS_ERRNO_DECL 1 // * errno.h declares errno */
|
||||
#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
|
||||
//#define HAS_LIMITS_H 1 // * /usr/include/limits.h */
|
||||
#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
|
||||
//#define HAS_ERRNO_DECL 1 // * errno.h declares errno */
|
||||
|
||||
#define HAS_FSTAT 1 /* fstat syscall */
|
||||
#define HAS_FCHMOD 1 /* fchmod syscall */
|
||||
#define HAS_CHMOD 1 /* chmod syscall */
|
||||
#define HAS_FCHOWN 1 /* fchown syscall */
|
||||
#define HAS_CHOWN 1 /* chown syscall */
|
||||
/*efine HAS__FSETMODE 1 // * _fsetmode -- set file mode */
|
||||
#define HAS_FSTAT 1 /* fstat syscall */
|
||||
#define HAS_FCHMOD 1 /* fchmod syscall */
|
||||
#define HAS_CHMOD 1 /* chmod syscall */
|
||||
#define HAS_FCHOWN 1 /* fchown syscall */
|
||||
#define HAS_CHOWN 1 /* chown syscall */
|
||||
//#define HAS__FSETMODE 1 // * _fsetmode -- set file mode */
|
||||
|
||||
#define HAS_STRING_H 1 /* /usr/include/string.h */
|
||||
/*efine HAS_STRINGS_H 1 // * /usr/include/strings.h */
|
||||
#define HAS_STRING_H 1 /* /usr/include/string.h */
|
||||
//#define HAS_STRINGS_H 1 // * /usr/include/strings.h */
|
||||
|
||||
#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
|
||||
#define HAS_UTIME 1 /* POSIX utime(path, times) */
|
||||
/*efine HAS_UTIMES 1 // * use utimes() syscall instead */
|
||||
#define HAS_UTIME_H 1 /* UTIME header file */
|
||||
/*efine HAS_UTIMBUF 1 // * struct utimbuf */
|
||||
/*efine HAS_UTIMEUSEC 1 // * microseconds in utimbuf? */
|
||||
#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
|
||||
#define HAS_UTIME 1 /* POSIX utime(path, times) */
|
||||
//#define HAS_UTIMES 1 // * use utimes() syscall instead*/
|
||||
#define HAS_UTIME_H 1 /* UTIME header file */
|
||||
//#define HAS_UTIMBUF 1 // * struct utimbuf */
|
||||
//#define HAS_UTIMEUSEC 1 // * microseconds in utimbuf? */
|
||||
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
|
||||
|
|
|
@ -18,6 +18,17 @@
|
|||
*/
|
||||
#include "test.h"
|
||||
|
||||
|
||||
/* Any tests that want to build a linked executable for RTEMS must include
|
||||
this header to get a default config for the network stack. */
|
||||
#if defined(PJ_RTEMS)
|
||||
# include <bsp.h>
|
||||
# include <rtems.h>
|
||||
# include <rtems/rtems_bsdnet.h>
|
||||
# include "../../../pjlib/include/rtems-network-config.h"
|
||||
#endif
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int rc;
|
||||
|
|
Loading…
Reference in New Issue