Copied latest stuff from /m/src/ns/nspr20. NSPRPUB_19980508_BRANCH
authorwtc
Fri, 08 May 1998 23:30:48 +0000
branchNSPRPUB_19980508_BRANCH
changeset 115 9afe4ea6bbc4b3652bc3f304dc237eb0249e6fd9
parent 114 ed63234acf412516e1b54518041cbdac8b1d7fd1
push idunknown
push userunknown
push dateunknown
Copied latest stuff from /m/src/ns/nspr20.
config/NEWS-OS.mk
config/OS2.mk
config/SINIX.mk
config/SunOS5.mk
config/WIN32.mk
config/arch.mk
config/win16.mk
pr/include/md/_os2.h
pr/include/md/_unixos.h
pr/include/md/_win16.h
pr/include/md/_win95.h
pr/include/md/_winnt.h
pr/include/prclist.h
pr/include/prlog.h
pr/src/io/prlog.c
pr/src/linking/prlink.c
pr/src/md/unix/pthreads_user.c
pr/src/md/unix/solaris.c
pr/src/md/unix/unix.c
pr/src/md/windows/ntio.c
pr/src/md/windows/ntthread.c
pr/src/misc/prenv.c
pr/src/pthreads/ptsynch.c
pr/src/threads/combined/prucpu.c
pr/tests/Makefile
pr/tests/logger.c
pr/tests/sleep.c
pr/tests/time.c
--- a/config/NEWS-OS.mk
+++ b/config/NEWS-OS.mk
@@ -32,17 +32,17 @@ CC			= cc
 CCC			= CC
 RANLIB			= /bin/true
 
 OS_INCLUDES		= -I/usr/include
 G++INCLUDES		=
 #OS_LIBS			= -lsocket -lnsl -lgen -lresolv
 
 PLATFORM_FLAGS		= -Xa -fullwarn -DSONY
-PORT_FLAGS		= -DSYSV -DSVR4 -D__svr4 -D__svr4__ -D_PR_LOCAL_THREADS_ONLY
+PORT_FLAGS		= -DSYSV -DSVR4 -D__svr4 -D__svr4__ -D_PR_LOCAL_THREADS_ONLY -DHAVE_SVID_GETTOD
 
 OS_CFLAGS		= $(PLATFORM_FLAGS) $(PORT_FLAGS)
 
 ######################################################################
 # Version-specific stuff
 ######################################################################
 
 ######################################################################
--- a/config/OS2.mk
+++ b/config/OS2.mk
@@ -69,17 +69,17 @@ OBJDIR_TAG = _DBG
 LDFLAGS = -DEBUG 
 endif
 
 DEFINES += -DOS2=4 -DBSD_SELECT
 DEFINES += -D_X86_
 DEFINES += -D_PR_GLOBAL_THREADS_ONLY
 
 # Name of the binary code directories
-ifeq ($(CPU_ARCH),x386)
+ifeq ($(CPU_ARCH),x86)
 ifdef MOZ_LITE
 OBJDIR_NAME = $(subst OS2,NAV,$(OS_CONFIG))$(OBJDIR_TAG).OBJ
 else
 OBJDIR_NAME = $(OS_CONFIG)$(OBJDIR_TAG).OBJ
 endif
 else
 OBJDIR_NAME = $(OS_CONFIG)$(CPU_ARCH)$(OBJDIR_TAG).OBJ
 endif
--- a/config/SINIX.mk
+++ b/config/SINIX.mk
@@ -48,17 +48,17 @@ ODD_CFLAGS		=
 ifdef BUILD_OPT
 #OPTIMIZER		= -Olimit 4000
 OPTIMIZER		= -O -F Olimit,4000
 endif
 MKSHLIB			= $(LD) -G -z defs -h $(@:$(OBJDIR)/%.so=%.so)
 #DSO_LDOPTS		= -G -W l,-Blargedynsym
 endif
 
-ODD_CFLAGS		+= -DSVR4 -DSNI -DRELIANTUNIX -Dsinix -D_SVID_GETTOD
+ODD_CFLAGS		+= -DSVR4 -DSNI -DRELIANTUNIX -Dsinix -DHAVE_SVID_GETTOD
 
 # On SINIX 5.43, need to define IP_MULTICAST in order to get the
 # IP multicast macro and struct definitions in netinet/in.h.
 # (SINIX 5.42 does not have IP multicast at all.)
 ifeq ($(OS_RELEASE),5.43)
 ODD_CFLAGS		+= -DIP_MULTICAST
 endif
 
--- a/config/SunOS5.mk
+++ b/config/SunOS5.mk
@@ -100,21 +100,16 @@ CPU_ARCH		= x86
 CPU_ARCH_TAG		= _i86pc
 OS_DEFINES		+= -Di386
 else
 CPU_ARCH		= sparc
 endif
 
 ifeq (5.5,$(findstring 5.5,$(OS_RELEASE)))
 OS_DEFINES		+= -DSOLARIS2_5
-SOL_CFLAGS		= -D_SVID_GETTOD
-endif
-
-ifeq ($(OS_RELEASE),5.6)
-SOL_CFLAGS		= -D_SVID_GETTOD
 endif
 
 ifneq ($(LOCAL_THREADS_ONLY),1)
 OS_DEFINES		+= -D_REENTRANT
 endif
 
 # Purify doesn't like -MDupdate
 NOMD_OS_CFLAGS		= $(DSO_CFLAGS) $(OS_DEFINES) $(SOL_CFLAGS)
--- a/config/WIN32.mk
+++ b/config/WIN32.mk
@@ -24,16 +24,32 @@
 # Client build: make sure we use the shmsdos.exe under $(MOZ_TOOLS).
 # $(MOZ_TOOLS_FLIPPED) is $(MOZ_TOOLS) with all the backslashes
 # flipped, so that gmake won't interpret them as escape characters.
 #
 ifdef PR_CLIENT_BUILD_WINDOWS
 SHELL = $(MOZ_TOOLS_FLIPPED)/bin/shmsdos.exe
 endif
 
+#
+# On NT, we use static thread local storage by default because it
+# gives us better performance.  However, we can't use static TLS
+# on Alpha NT because the Alpha version of MSVC does not seem to
+# support the -GT flag, which is necessary to make static TLS safe
+# for fibers.
+#
+# On Win95, we use the TlsXXX() functions by default because that
+# allows us to load the NSPR DLL at run time using LoadLibrary().
+#
+ifeq ($(OS_TARGET),WINNT)
+ifneq ($(CPU_ARCH),ALPHA)
+USE_STATIC_TLS = 1
+endif
+endif
+
 CC = cl
 CCC = cl
 LINK = link
 AR = lib -NOLOGO -OUT:"$@"
 RANLIB = echo
 BSDECHO = echo
 NSINSTALL = nsinstall
 INSTALL	= $(NSINSTALL)
@@ -91,43 +107,57 @@ OPTIMIZER = -Od -Z7
 DEFINES = -DDEBUG -D_DEBUG -UNDEBUG
 DLLFLAGS = -DEBUG -DEBUGTYPE:CV -OUT:"$@"
 OBJDIR_TAG = _DBG
 LDFLAGS = -DEBUG -DEBUGTYPE:CV
 endif
 endif
 
 DEFINES += -DWIN32
-ifeq ($(OS_TARGET),WINNT)
+ifeq ($(USE_STATIC_TLS),1)
+DEFINES += -D_PR_USE_STATIC_TLS
+endif
+
+#
+# NSPR uses fibers on NT.  Therefore, if we use static local
+# storage (i.e., __declspec(thread) variables), we need the -GT
+# flag to turn off certain compiler optimizations so that fibers
+# can use static TLS safely.
 #
-# Win NT needs -GT so that fibers can work
+# Also, we optimize for Pentium (-G5) on NT.
 #
+ifeq ($(OS_TARGET),WINNT)
+ifeq ($(USE_STATIC_TLS),1)
 OS_CFLAGS += -GT
+endif
+ifeq ($(CPU_ARCH),x86)
+OS_CFLAGS += -G5
+endif
 DEFINES += -DWINNT
 else
 DEFINES += -DWIN95 -D_PR_GLOBAL_THREADS_ONLY
 endif
 
-ifeq ($(CPU_ARCH),x386)
+ifeq ($(CPU_ARCH),x86)
 DEFINES += -D_X86_
 else
 ifeq ($(CPU_ARCH),MIPS)
 DEFINES += -D_MIPS_
 else
 ifeq ($(CPU_ARCH),ALPHA)
 DEFINES += -D_ALPHA_=1
 else
 CPU_ARCH = processor_is_undefined
 endif
 endif
 endif
 
 # Name of the binary code directories
 
-ifeq ($(CPU_ARCH),x386)
+ifeq ($(CPU_ARCH),x86)
 CPU_ARCH_TAG =
 else
 CPU_ARCH_TAG = $(CPU_ARCH)
 endif
 
 ifdef USE_DEBUG_RTL
 OBJDIR_SUFFIX = OBJD
 else
--- a/config/arch.mk
+++ b/config/arch.mk
@@ -139,17 +139,17 @@ endif
 
 #
 # On WIN32, we also define the variable CPU_ARCH.
 #
 
 ifeq ($(OS_ARCH), WINNT)
 	CPU_ARCH := $(shell uname -p)
 	ifeq ($(CPU_ARCH),I386)
-		CPU_ARCH = x386
+		CPU_ARCH = x86
 	endif
 else
 #
 # If uname -s returns "Windows_NT", we assume that we are using
 # the uname.exe in MKS toolkit.
 #
 # The -r option of MKS uname only returns the major version number.
 # So we need to use its -v option to get the minor version number.
@@ -162,31 +162,31 @@ ifeq ($(OS_ARCH), Windows_NT)
 		OS_MINOR_RELEASE = 0
 	endif
 	OS_RELEASE := $(OS_RELEASE).$(OS_MINOR_RELEASE)
 	CPU_ARCH := $(shell uname -m)
 	#
 	# MKS's uname -m returns "586" on a Pentium machine.
 	#
 	ifneq (,$(findstring 86,$(CPU_ARCH)))
-		CPU_ARCH = x386
+		CPU_ARCH = x86
 	endif
 else
 #
 # If uname -s returns "CYGWIN32/NT", we assume that we are using
 # the uname.exe in the GNU-Win32 tools.
 #
 ifeq ($(OS_ARCH), CYGWIN32_NT)
 	OS_ARCH = WINNT
 	CPU_ARCH := $(shell uname -m)
 	#
 	# GNU-Win32's uname -m returns "i686" on a Pentium Pro machine.
 	#
 	ifneq (,$(findstring 86,$(CPU_ARCH)))
-		CPU_ARCH = x386
+		CPU_ARCH = x86
 	endif
 endif
 endif
 endif
 
 ifndef OS_TARGET
 	OS_TARGET := $(OS_ARCH)
 endif
--- a/config/win16.mk
+++ b/config/win16.mk
@@ -80,17 +80,17 @@ endif
 
 # XXX FIXME: I doubt we use this.  It is redundant with
 # SHARED_LIBRARY.
 ifdef DLL
 DLL := $(addprefix $(OBJDIR)/, $(DLL))
 endif
 
 
-CPU_ARCH = x386
+CPU_ARCH = x86
 OS_CFLAGS = -ml -3 -bd -zc -zu -bt=windows -d_X86_ -dWIN16 -d_WINDLL
 OS_EXE_CFLAGS = -ml -3 -bt=windows -d_X86_ -dWIN16
 OS_LIB_FLAGS = -c -iro -n
 
 # Name of the binary code directories
 OBJDIR_NAME     = $(OS_CONFIG)$(OBJDIR_TAG).OBJ
 
 OS_DLL_OPTION = CASEEXACT
--- a/pr/include/md/_os2.h
+++ b/pr/include/md/_os2.h
@@ -397,21 +397,16 @@ PR_IMPLEMENT(void) _PR_MD_ENSURE_TLS();
 #define _MD_SET_CURRENT_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentThread = (_thread)
 
 #define _MD_LAST_THREAD() pThreadLocalStorage->_pr_thread_last_run
 #define _MD_SET_LAST_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_thread_last_run = (_thread)
 
 #define _MD_CURRENT_CPU() pThreadLocalStorage->_pr_currentCPU
 #define _MD_SET_CURRENT_CPU(_cpu) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentCPU = (_cpu)
 
-/* lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) */
-/* lth. #define _MD_GET_INTSOFF() _pr_ints_off */
-/* lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++) */
-/* lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--) */
-
 /* --- Scheduler stuff --- */
 #define LOCK_SCHEDULER()                 0
 #define UNLOCK_SCHEDULER()               0
 #define _PR_LockSched()                	 0
 #define _PR_UnlockSched()                0
 
 /* --- Initialization stuff --- */
 #define _MD_INIT_LOCKS()
--- a/pr/include/md/_unixos.h
+++ b/pr/include/md/_unixos.h
@@ -459,16 +459,27 @@ extern void * _MD_MemMap(struct PRFileMa
 #define _MD_MEM_MAP _MD_MemMap
 
 extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
 #define _MD_MEM_UNMAP _MD_MemUnmap
 
 extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
 #define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
 
+/*
+ * The standard (XPG4) gettimeofday() (from BSD) takes two arguments.
+ * On some SVR4 derivatives, gettimeofday() takes only one argument.
+ * The GETTIMEOFDAY macro is intended to hide this difference.
+ */
+#ifdef HAVE_SVID_GETTOD
+#define GETTIMEOFDAY(tp) gettimeofday(tp)
+#else
+#define GETTIMEOFDAY(tp) gettimeofday((tp), NULL)
+#endif
+
 #if defined(LINUX) && defined(_PR_PTHREADS) && !(__GLIBC__ >= 2)
 #define _PR_NEED_FAKE_POLL
 #endif
 
 #if defined(_PR_NEED_FAKE_POLL)
 
 /*
  * Some platforms don't have poll(), but our pthreads code calls poll().
--- a/pr/include/md/_win16.h
+++ b/pr/include/md/_win16.h
@@ -40,18 +40,16 @@
 #define _PR_NO_PREEMPT
 #define _PR_LOCAL_THREADS_ONLY
 #undef  _PR_GLOBAL_THREADS_ONLY
 #undef  HAVE_THREAD_AFFINITY
 #define HAVE_SOCKET_REUSEADDR
 #define HAVE_SOCKET_KEEPALIVE
 #define _PR_HAVE_ATOMIC_OPS
 
-typedef char * caddr_t;
-
 /* --- Common User-Thread/Native-Thread Definitions --------------------- */
 
 extern struct PRLock        *_pr_schedLock;
 extern char                 * _pr_top_of_task_stack;
 
 
 /* --- Typedefs --- */
 
--- a/pr/include/md/_win95.h
+++ b/pr/include/md/_win95.h
@@ -34,19 +34,16 @@
 #define _PR_SI_ARCHITECTURE   "x86"    /* XXXMB hardcode for now */
 
 #define HAVE_DLL
 #undef  HAVE_THREAD_AFFINITY
 #define HAVE_SOCKET_REUSEADDR
 #define HAVE_SOCKET_KEEPALIVE
 #define _PR_HAVE_ATOMIC_OPS
 
-typedef char * caddr_t;
-typedef int    ptrdiff_t;   /* used in prnetdb.h */
-
 /* --- Common User-Thread/Native-Thread Definitions --------------------- */
 
 /* --- Globals --- */
 extern struct PRLock                      *_pr_schedLock;
 
 /* --- Typedefs --- */
 typedef void (*FiberFunc)(void *);
 
@@ -373,41 +370,35 @@ extern PRStatus _PR_KillWindowsProcess(s
 
 #ifdef _PR_USE_STATIC_TLS
 extern __declspec(thread) struct PRThread *_pr_currentThread;
 #define _MD_CURRENT_THREAD() _pr_currentThread
 #define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
 
 extern __declspec(thread) struct PRThread *_pr_thread_last_run;
 #define _MD_LAST_THREAD() _pr_thread_last_run
-#define _MD_SET_LAST_THREAD(_thread) (_pr_thread_last_run = (0))
+#define _MD_SET_LAST_THREAD(_thread) (_pr_thread_last_run = 0)
 
 extern __declspec(thread) struct _PRCPU *_pr_currentCPU;
 #define _MD_CURRENT_CPU() _pr_currentCPU
-#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (0))
+#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = 0)
 #else /* _PR_USE_STATIC_TLS */
 extern DWORD _pr_currentThreadIndex;
 #define _MD_CURRENT_THREAD() ((PRThread *) TlsGetValue(_pr_currentThreadIndex))
-#define _MD_SET_CURRENT_THREAD(_thread) TlsSetValue(_pr_currentThreadIndex, _thread)
+#define _MD_SET_CURRENT_THREAD(_thread) TlsSetValue(_pr_currentThreadIndex, (_thread))
 
 extern DWORD _pr_lastThreadIndex;
 #define _MD_LAST_THREAD() ((PRThread *) TlsGetValue(_pr_lastThreadIndex))
 #define _MD_SET_LAST_THREAD(_thread) TlsSetValue(_pr_lastThreadIndex, 0)
 
 extern DWORD _pr_currentCPUIndex;
 #define _MD_CURRENT_CPU() ((struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex))
 #define _MD_SET_CURRENT_CPU(_cpu) TlsSetValue(_pr_currentCPUIndex, 0)
 #endif /* _PR_USE_STATIC_TLS */
 
-// wtc. extern __declspec(thread) PRUintn _pr_ints_off;
-// lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val))
-// lth. #define _MD_GET_INTSOFF() _pr_ints_off
-// lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++)
-// lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--)
-
 /* --- Scheduler stuff --- */
 #define LOCK_SCHEDULER()                 0
 #define UNLOCK_SCHEDULER()               0
 #define _PR_LockSched()                	 0
 #define _PR_UnlockSched()                0
 
 /* --- Initialization stuff --- */
 #define _MD_INIT_LOCKS()
--- a/pr/include/md/_winnt.h
+++ b/pr/include/md/_winnt.h
@@ -45,20 +45,16 @@
 
 #define HAVE_DLL
 #define HAVE_CUSTOM_USER_THREADS
 #define HAVE_THREAD_AFFINITY
 #define HAVE_SOCKET_REUSEADDR
 #define HAVE_SOCKET_KEEPALIVE
 #define _PR_HAVE_ATOMIC_OPS
 
-typedef char * caddr_t;
-typedef int    ptrdiff_t;   /* used in prnetdb.h */
-
-
 /* --- Common User-Thread/Native-Thread Definitions --------------------- */
 
 /* --- Globals --- */
 extern struct PRLock                      *_pr_schedLock;
 
 /* --- Typedefs --- */
 typedef void (*FiberFunc)(void *);
 
@@ -369,33 +365,53 @@ extern PRStatus _PR_KillWindowsProcess(s
 #define _MD_INTERVAL_INIT                 _PR_MD_INTERVAL_INIT
 #define _MD_GET_INTERVAL                  _PR_MD_GET_INTERVAL
 #define _MD_INTERVAL_PER_SEC              _PR_MD_INTERVAL_PER_SEC
 #define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
 #define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
 
 /* --- Native-Thread Specific Definitions ------------------------------- */
 
+#ifdef _PR_USE_STATIC_TLS
+
 extern __declspec(thread) struct PRThread *_pr_current_fiber;
 #define _MD_CURRENT_THREAD() _pr_current_fiber
 #define _MD_SET_CURRENT_THREAD(_thread) (_pr_current_fiber = (_thread))
 
 extern __declspec(thread) struct PRThread *_pr_fiber_last_run;
 #define _MD_LAST_THREAD() _pr_fiber_last_run
 #define _MD_SET_LAST_THREAD(_thread) (_pr_fiber_last_run = (_thread))
 
 extern __declspec(thread) struct _PRCPU *_pr_current_cpu;
 #define _MD_CURRENT_CPU() _pr_current_cpu
 #define _MD_SET_CURRENT_CPU(_cpu) (_pr_current_cpu = (_cpu))
 
 extern __declspec(thread) PRUintn _pr_ints_off;
 #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val))
 #define _MD_GET_INTSOFF() _pr_ints_off
-#define _MD_INCREMENT_INTSOFF() (_pr_ints_off++)
-#define _MD_DECREMENT_INTSOFF() (_pr_ints_off--)
+
+#else /* _PR_USE_STATIC_TLS */
+
+extern DWORD _pr_currentFiberIndex;
+#define _MD_CURRENT_THREAD() ((PRThread *) TlsGetValue(_pr_currentFiberIndex))
+#define _MD_SET_CURRENT_THREAD(_thread) TlsSetValue(_pr_currentFiberIndex, (_thread))
+
+extern DWORD _pr_lastFiberIndex;
+#define _MD_LAST_THREAD() ((PRThread *) TlsGetValue(_pr_lastFiberIndex))
+#define _MD_SET_LAST_THREAD(_thread) TlsSetValue(_pr_lastFiberIndex, (_thread))
+
+extern DWORD _pr_currentCPUIndex;
+#define _MD_CURRENT_CPU() ((struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex))
+#define _MD_SET_CURRENT_CPU(_cpu) TlsSetValue(_pr_currentCPUIndex, (_cpu))
+
+extern DWORD _pr_intsOffIndex;
+#define _MD_SET_INTSOFF(_val) TlsSetValue(_pr_intsOffIndex, (LPVOID) (_val))
+#define _MD_GET_INTSOFF() ((PRUintn) TlsGetValue(_pr_intsOffIndex))
+
+#endif /* _PR_USE_STATIC_TLS */
 
 /* --- Initialization stuff --- */
 #define _MD_INIT_LOCKS()
 
 /* --- Stack stuff --- */
 #define _MD_INIT_STACK(stack, redzone)
 #define _MD_CLEAR_STACK(stack)
 
--- a/pr/include/prclist.h
+++ b/pr/include/prclist.h
@@ -54,16 +54,22 @@ struct PRCListStr {
     PR_END_MACRO
 
 /*
 ** Return the element following element "_e"
 */
 #define PR_NEXT_LINK(_e)	 \
     	((_e)->next)
 /*
+** Return the element preceding element "_e"
+*/
+#define PR_PREV_LINK(_e)	 \
+    	((_e)->prev)
+
+/*
 ** Append an element "_e" to the end of the list "_l"
 */
 #define PR_APPEND_LINK(_e,_l) PR_INSERT_BEFORE(_e,_l)
 
 /*
 ** Insert an element "_e" at the head of the list "_l"
 */
 #define PR_INSERT_LINK(_e,_l) PR_INSERT_AFTER(_e,_l)
--- a/pr/include/prlog.h
+++ b/pr/include/prlog.h
@@ -19,40 +19,101 @@
 #ifndef prlog_h___
 #define prlog_h___
 
 #include "prtypes.h"
 
 PR_BEGIN_EXTERN_C
 
 /*
+** prlog.h -- Declare interfaces to NSPR's Logging service
 **
-** Define in your environment a NSPR_LOG_MODULES variable. The value of
-** this variable has the form:
+** NSPR provides a logging service that is used by NSPR itself and is
+** available to client programs.
+**
+** To use the service from a client program, you should create a
+** PRLogModuleInfo structure by calling PR_NewLogModule(). After
+** creating the LogModule, you can write to the log using the PR_LOG()
+** macro.
+**
+** Initialization of the log service is handled by NSPR initialization.
+**
+** At execution time, you must enable the log service. To enable the
+** log service, set the environment variable: NSPR_LOG_MODULES
+** variable.
+**
+** NSPR_LOG_MODULES variable has the form:
 **
 **     <moduleName>:<value>[, <moduleName>:<value>]*
 **
-** where moduleName is one of named modules that support debugging (see
-** the header file for a particular module for more specific
-** information).  Value is one of the enum PRLogModuleLevel's legal
-** values.
+** Where:
+**  <moduleName> is the name passed to PR_NewLogModule().
+**  <value> is a numeric constant, e.g. 5. This value is the maximum
+** value of a log event, enumerated by PRLogModuleLevel, that you want
+** written to the log.
+** 
+** For example: to record all events of greater value than or equal to
+** PR_LOG_ERROR for a LogModule names "gizmo", say:
+** 
+** set NSPR_LOG_MODULES=gizmo:2
+** 
+** Note that you must specify the numeric value of PR_LOG_ERROR.
+** 
+** Special LogModule names are provided for controlling NSPR's log
+** service at execution time. These controls should be set in the
+** NSPR_LOG_MODULES environment variable at execution time to affect
+** NSPR's log service for your application.
+** 
+** The special LogModule "all" enables all LogModules. To enable all
+** LogModule calls to PR_LOG(), say:
+** 
+** set NSPR_LOG_MODULES=all:5
+** 
+** The special LogModule name "sync" tells the NSPR log service to do
+** unbuffered logging.
+** 
+** The special LogModule name "buffsize:<size>" tells NSPR to set the
+** log buffer to <size>.
 **
-** Special modules exist for controlling the logging facility:
-**    sync        -- do unbuffered logging
-**    bufsize:size    -- use a buffer of "size" bytes
-**
-** Define in your environment NSPR_LOG_FILE to specify the log file to
-** use unless the default of "stderr" is acceptable.
+** The environment variable NSPR_LOG_FILE specifies the log file to use
+** unless the default of "stderr" is acceptable.
 **
 ** To put log messages in your programs, use the PR_LOG macro:
 **
 **     PR_LOG(<module>, <level>, (<printfString>, <args>*));
 **
 ** Where <module> is the address of a PRLogModuleInfo structure, and
-** <level> is one of the following levels:
+** <level> is one of the levels defined by the enumeration:
+** PRLogModuleLevel. <args> is a printf() style of argument list. That
+** is: (fmtstring, ...).
+**
+** Example:
+** 
+** main() {
+**    PRIntn one = 1;
+**    PRLogModuleInfo * myLm = PR_NewLogModule("gizmo");
+**    PR_LOG( myLm, PR_LOG_ALWAYS, ("Log this! %d\n", one)); 
+**    return; 
+** }
+** 
+** Note the use of printf() style arguments as the third agrument(s) to
+** PR_LOG().
+** 
+** After compiling and linking you application, set the environment:
+** 
+** SET NSPR_LOGMODULES=gizmo:5
+** SET NSPR_LOG_FILE=logfile.txt
+** 
+** When you execute your application, the string "Log this! 1" will be
+** written to the file "logfile.txt".
+** 
+** Note to NSPR engineers: a number of PRLogModuleInfo structures are
+** defined and initialized in prinit.c. See this module for ideas on
+** what to log where.
+** 
 */
 
 typedef enum PRLogModuleLevel {
     PR_LOG_NONE = 0,                /* nothing */
     PR_LOG_ALWAYS = 1,              /* always printed */
     PR_LOG_ERROR = 2,               /* error messages */
     PR_LOG_WARNING = 3,             /* warning messages */
     PR_LOG_DEBUG = 4,               /* debug messages */
--- a/pr/src/io/prlog.c
+++ b/pr/src/io/prlog.c
@@ -244,29 +244,76 @@ void _PR_LogCleanup(void)
     if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) {
         PR_Close(logFile);
     }
 #endif
 }
 
 #endif /* PR_LOGGING */
 
+static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm )
+{
+#ifdef PR_LOGGING
+    char *ev;
+
+    ev = PR_GetEnv("NSPR_LOG_MODULES");
+    if (ev && ev[0]) {
+        char module[64];
+        PRBool isSync = PR_FALSE;
+        PRIntn evlen = strlen(ev), pos = 0;
+        PRInt32 bufSize = DEFAULT_BUF_SIZE;
+        while (pos < evlen) {
+            PRIntn level = 1, count = 0, delta = 0;
+            PRLogModuleInfo *lm = logModules;
+            PRBool skip_modcheck;
+
+            count = sscanf(&ev[pos], "%64[A-Za-z0-9]%n:%d%n",
+                           module, &delta, &level, &delta);
+            pos += delta;
+            if (count == 0) break;
+
+            /*
+            ** If count == 2, then we got module and level. If count
+            ** == 1, then level defaults to 1 (module enabled).
+            */
+            skip_modcheck = (0 == strcasecmp (module, "all")) ? PR_TRUE : PR_FALSE;
+            while (lm != NULL) 
+            {
+                if (skip_modcheck) 
+                    lm->level = (PRLogModuleLevel)level;
+                else if (strcasecmp(module, lm->name) == 0) 
+                {
+                    lm->level = level;
+                    break;
+                }
+                lm = lm->next;
+            }
+            /*found:*/
+            count = sscanf(&ev[pos], " , %n", &delta);
+            pos += delta;
+            if (count == -1) break;
+        }
+    }
+#endif /* PR_LOGGING */
+} /* end _PR_SetLogModuleLevel() */
+
 PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name)
 {
     PRLogModuleInfo *lm;
 
         if (!_pr_initialized) _PR_ImplicitInitialization();
 
     lm = PR_NEWZAP(PRLogModuleInfo);
     if (lm) {
         lm->name = strdup(name);
         lm->level = PR_LOG_NONE;
         lm->next = logModules;
         logModules = lm;
     }
+    _PR_SetLogModuleLevel(lm);
     return lm;
 }
 
 PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file)
 {
 #ifdef PR_LOGGING
 #ifdef _PR_USE_STDIO_FOR_LOGGING
     FILE *newLogFile;
--- a/pr/src/linking/prlink.c
+++ b/pr/src/linking/prlink.c
@@ -941,16 +941,18 @@ PR_FindSymbolAndLibrary(const char *raw_
 ** is called with the name then we will pretend it was already loaded
 */
 PR_IMPLEMENT(PRLibrary*) 
 PR_LoadStaticLibrary(const char *name, const PRStaticLinkTable *slt)
 {
     PRLibrary *lm=NULL;
     PRLibrary* result = NULL;
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
     /* See if library is already loaded */
     PR_EnterMonitor(pr_linker_lock);
 
     /* If the lbrary is already loaded, then add the static table information... */
     result = pr_UnlockedFindLibrary(name);
     if (result != NULL) {
         PR_ASSERT( (result->staticTable == NULL) || (result->staticTable == slt) );
         result->staticTable = slt;
--- a/pr/src/md/unix/pthreads_user.c
+++ b/pr/src/md/unix/pthreads_user.c
@@ -233,21 +233,17 @@ PRUint32 ticks = PR_TicksPerSecond();
 
 	if (timeout != PR_INTERVAL_NO_TIMEOUT) {
 		tmo.tv_sec = timeout / ticks;
 		tmo.tv_nsec = timeout - (tmo.tv_sec * ticks);
 		tmo.tv_nsec = PR_IntervalToMicroseconds(PT_NANOPERMICRO *
 											tmo.tv_nsec);
 
 		/* pthreads wants this in absolute time, off we go ... */
-#if defined(SOLARIS) && defined(_SVID_GETTOD)
-		(void)gettimeofday(&now);
-#else
-		(void)gettimeofday(&now, NULL);
-#endif
+		(void)GETTIMEOFDAY(&now);
 		/* that one's usecs, this one's nsecs - grrrr! */
 		tmo.tv_sec += now.tv_sec;
 		tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
 		tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
 		tmo.tv_nsec %= PT_BILLION;
 	}
 
 	pthread_mutex_lock(&thread->md.pthread_mutex);
--- a/pr/src/md/unix/solaris.c
+++ b/pr/src/md/unix/solaris.c
@@ -794,15 +794,15 @@ int
 {
     struct timeval tv;
 
     if (clock_id != CLOCK_REALTIME) {
 	errno = EINVAL;
 	return -1;
     }
 
-    gettimeofday(&tv);
+    gettimeofday(&tv, NULL);
     tp->tv_sec = tv.tv_sec;
     tp->tv_nsec = tv.tv_usec * 1000;
     return 0;
 }
 #endif  /* i386 && SOLARIS2_4 */
 #endif  /* _PR_PTHREADS */
--- a/pr/src/md/unix/unix.c
+++ b/pr/src/md/unix/unix.c
@@ -2852,39 +2852,31 @@ void _MD_FreeSegment(PRSegment *seg)
  */
 
 PR_IMPLEMENT(PRTime)
 PR_Now(void)
 {
 	struct timeval tv;
 	PRInt64 s, us, s2us;
 
-#if (defined(SOLARIS) && defined(_SVID_GETTOD)) || defined(SONY)
-	gettimeofday(&tv);
-#else
-	gettimeofday(&tv, 0);
-#endif
+	GETTIMEOFDAY(&tv);
 	LL_I2L(s2us, PR_USEC_PER_SEC);
 	LL_I2L(s, tv.tv_sec);
 	LL_I2L(us, tv.tv_usec);
 	LL_MUL(s, s, s2us);
 	LL_ADD(s, s, us);
 	return s;
 }
 
 PRIntervalTime _PR_UNIX_GetInterval()
 {
 	struct timeval time;
 	PRIntervalTime ticks;
 
-#if defined(_SVID_GETTOD) || defined(SONY)
-	(void)gettimeofday(&time);  /* fallicy of course */
-#else
-	(void)gettimeofday(&time, NULL);  /* fallicy of course */
-#endif
+	(void)GETTIMEOFDAY(&time);  /* fallicy of course */
 	ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
 	ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
 	return ticks;
 }  /* _PR_SUNOS_GetInterval */
 
 PRIntervalTime _PR_UNIX_TicksPerSecond()
 {
 	return 1000;  /* this needs some work :) */
--- a/pr/src/md/windows/ntio.c
+++ b/pr/src/md/windows/ntio.c
@@ -40,17 +40,23 @@
 static HANDLE                _pr_completion_port;
 static PRThread             *_pr_io_completion_thread;
 
 #define RECYCLE_SIZE 512
 static struct _MDLock        _pr_recycle_lock;
 static PRInt32               _pr_recycle_array[RECYCLE_SIZE];
 static PRInt32               _pr_recycle_tail = 0; 
 
+#ifdef _PR_USE_STATIC_TLS
 __declspec(thread) PRThread *_pr_io_restarted_io = NULL;
+#else
+DWORD _pr_io_restartedIOIndex;  /* The thread local storage slot for each
+                                 * thread is initialized to NULL. */
+#endif
+
 PRBool                       _nt_version_gets_lockfile_completion;
 
 struct _MDLock               _pr_ioq_lock;
 extern _MDLock               _nt_idleLock;
 extern PRCList               _nt_idleList;
 extern PRUint32              _nt_idleCount;
 
 #define CLOSE_TIMEOUT   PR_SecondsToInterval(5)
@@ -466,17 +472,21 @@ void _PR_Unblock_IO_Wait(PRThread *thr)
 
 /* Resume an outstanding IO; requires that after the switch, we disable */
 static PRStatus
 _NT_ResumeIO(PRThread *thread, PRIntervalTime ticks)
 {
     PRBool fWait = PR_TRUE;
 
     if (!_PR_IS_NATIVE_THREAD(thread)) {
+#ifdef _PR_USE_STATIC_TLS
         _pr_io_restarted_io = thread;
+#else
+        TlsSetValue(_pr_io_restartedIOIndex, thread);
+#endif
     } else {
         _PR_THREAD_LOCK(thread);
         if (!thread->io_pending)
             fWait = PR_FALSE;
         thread->io_suspended = PR_FALSE;
             
         _PR_THREAD_UNLOCK(thread);
     }
--- a/pr/src/md/windows/ntthread.c
+++ b/pr/src/md/windows/ntthread.c
@@ -19,33 +19,58 @@
 #include "primpl.h"
 #include <process.h>  /* for _beginthreadex() */
 
 extern void _PR_Win32InitTimeZone(void);  /* defined in ntmisc.c */
 
 /* --- globals ------------------------------------------------ */
 PRLock                       *_pr_schedLock = NULL;
 _PRInterruptTable             _pr_interruptTable[] = { { 0 } };
+
+#ifdef _PR_USE_STATIC_TLS
 __declspec(thread) PRThread  *_pr_current_fiber;
 __declspec(thread) PRThread  *_pr_fiber_last_run;
 __declspec(thread) _PRCPU    *_pr_current_cpu;
 __declspec(thread) PRUintn    _pr_ints_off;
+#else /* _PR_USE_STATIC_TLS */
+DWORD _pr_currentFiberIndex;
+DWORD _pr_lastFiberIndex;
+DWORD _pr_currentCPUIndex;
+DWORD _pr_intsOffIndex;
+#endif /* _PR_USE_STATIC_TLS */
 
 _MDLock                       _nt_idleLock;
 PRCList                       _nt_idleList;
 PRUint32                        _nt_idleCount;
 
+#ifdef _PR_USE_STATIC_TLS
+
 extern __declspec(thread) PRThread *_pr_io_restarted_io;
 
 /* Must check the restarted_io *before* decrementing no_sched to 0 */
 #define POST_SWITCH_WORK() \
     if (_pr_io_restarted_io) \
         _nt_handle_restarted_io(_pr_io_restarted_io); \
     _PR_MD_LAST_THREAD()->no_sched = 0;
 
+#else /* _PR_USE_STATIC_TLS */
+
+extern DWORD _pr_io_restartedIOIndex;
+
+/* Must check the restarted_io *before* decrementing no_sched to 0 */
+#define POST_SWITCH_WORK() \
+PR_BEGIN_MACRO \
+    PRThread *restarted_io = (PRThread *) TlsGetValue(_pr_io_restartedIOIndex); \
+    if (restarted_io) \
+        _nt_handle_restarted_io(restarted_io); \
+    _PR_MD_LAST_THREAD()->no_sched = 0; \
+PR_END_MACRO
+
+#endif /* _PR_USE_STATIC_TLS */
+
 void
 _nt_handle_restarted_io(PRThread *restarted_io)
 {
     /* After the switch we can resume an IO if needed.
      * XXXMB - this needs to be done in create thread, since that could
      * be the result for a context switch too..
      */
     PR_ASSERT(restarted_io->io_suspended == PR_TRUE);
@@ -64,17 +89,21 @@ void
         _PR_SLEEPQ_LOCK(restarted_io->cpu);
         _PR_ADD_SLEEPQ(restarted_io, restarted_io->sleep);
         _PR_SLEEPQ_UNLOCK(restarted_io->cpu);
     }
     restarted_io->io_suspended = PR_FALSE;
 
     _PR_THREAD_UNLOCK(restarted_io);
 
+#ifdef _PR_USE_STATIC_TLS
     _pr_io_restarted_io = NULL;
+#else
+    TlsSetValue(_pr_io_restartedIOIndex, NULL);
+#endif
 }
 
 void
 _PR_MD_EARLY_INIT()
 {
     _MD_NEW_LOCK( &_nt_idleLock );
     _nt_idleCount = 0;
     PR_INIT_CLIST(&_nt_idleList);
@@ -82,21 +111,37 @@ void
 
 #if 0
     /* Make the clock tick at least once per millisecond */
     if ( timeBeginPeriod(1) == TIMERR_NOCANDO) {
         /* deep yoghurt; clock doesn't tick fast enough! */
         PR_ASSERT(0);
     }
 #endif
+
+#ifndef _PR_USE_STATIC_TLS
+    _pr_currentFiberIndex = TlsAlloc();
+    _pr_lastFiberIndex = TlsAlloc();
+    _pr_currentCPUIndex = TlsAlloc();
+    _pr_intsOffIndex = TlsAlloc();
+    _pr_io_restartedIOIndex = TlsAlloc();
+#endif
 }
 
 void _PR_MD_CLEANUP_BEFORE_EXIT(void)
 {
     WSACleanup();
+
+#ifndef _PR_USE_STATIC_TLS
+    TlsFree(_pr_currentFiberIndex);
+    TlsFree(_pr_lastFiberIndex);
+    TlsFree(_pr_currentCPUIndex);
+    TlsFree(_pr_intsOffIndex);
+    TlsFree(_pr_io_restartedIOIndex);
+#endif
 }
 
 void
 _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread)
 {
     /*
     ** Warning:
     ** --------
--- a/pr/src/misc/prenv.c
+++ b/pr/src/misc/prenv.c
@@ -20,24 +20,26 @@
 #include "primpl.h"
 
 /* Lock used to lock the environment */
 #if defined(_PR_NO_PREEMPT)
 #define _PR_NEW_LOCK_ENV()
 #define _PR_LOCK_ENV()
 #define _PR_UNLOCK_ENV()
 #elif defined(_PR_LOCAL_THREADS_ONLY)
+extern _PRCPU * _pr_primordialCPU;
+static PRIntn _is;
 #define _PR_NEW_LOCK_ENV()
-#define _PR_LOCK_ENV() { PRIntn _is; _PR_INTSOFF(_is)
-#define _PR_UNLOCK_ENV() _PR_INTSON(_is); }
+#define _PR_LOCK_ENV() if (_pr_primordialCPU) _PR_INTSOFF(_is);
+#define _PR_UNLOCK_ENV() if (_pr_primordialCPU) _PR_INTSON(_is);
 #else
-static PRLock *_pr_envLock;
+static PRLock *_pr_envLock = NULL;
 #define _PR_NEW_LOCK_ENV() {_pr_envLock = PR_NewLock();}
-#define _PR_LOCK_ENV() PR_Lock(_pr_envLock)
-#define _PR_UNLOCK_ENV() PR_Unlock(_pr_envLock)
+#define _PR_LOCK_ENV() { if (_pr_envLock) PR_Lock(_pr_envLock); }
+#define _PR_UNLOCK_ENV() { if (_pr_envLock) PR_Unlock(_pr_envLock); }
 #endif
 
 /************************************************************************/
 
 void _PR_InitEnv()
 {
 	_PR_NEW_LOCK_ENV();
 }
--- a/pr/src/pthreads/ptsynch.c
+++ b/pr/src/pthreads/ptsynch.c
@@ -225,21 +225,17 @@ static PRIntn pt_TimedWait(
     struct timespec tmo;
     PRUint32 ticks = PR_TicksPerSecond();
 
     tmo.tv_sec = (PRInt32)(timeout / ticks);
     tmo.tv_nsec = (PRInt32)(timeout - (tmo.tv_sec * ticks));
     tmo.tv_nsec = (PRInt32)PR_IntervalToMicroseconds(PT_NANOPERMICRO * tmo.tv_nsec);
 
     /* pthreads wants this in absolute time, off we go ... */
-#if defined(SOLARIS) && defined(_SVID_GETTOD)
-    (void)gettimeofday(&now);
-#else
-    (void)gettimeofday(&now, NULL);
-#endif
+    (void)GETTIMEOFDAY(&now);
     /* that one's usecs, this one's nsecs - grrrr! */
     tmo.tv_sec += now.tv_sec;
     tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
     tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
     tmo.tv_nsec %= PT_BILLION;
 
     rv = pthread_cond_timedwait(cv, ml, &tmo);
 
--- a/pr/src/threads/combined/prucpu.c
+++ b/pr/src/threads/combined/prucpu.c
@@ -13,17 +13,17 @@
  * The Initial Developer of this code under the NPL is Netscape
  * Communications Corporation.  Portions created by Netscape are
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 #include "primpl.h"
 
-_PRCPU *_pr_primordialCPU;
+_PRCPU *_pr_primordialCPU = NULL;
 
 PRInt32 _pr_md_idle_cpus;       /* number of idle cpus */
 /*
  * The idle threads in MxN models increment/decrement _pr_md_idle_cpus.
  * If _PR_HAVE_ATOMIC_OPS is not defined, they can't use the atomic
  * increment/decrement routines (which are based on PR_Lock/PR_Unlock),
  * because PR_Lock asserts that the calling thread is not an idle thread.
  * So we use a _MDLock to protect _pr_md_idle_cpus.
--- a/pr/tests/Makefile
+++ b/pr/tests/Makefile
@@ -44,16 +44,17 @@ CSRCS =             \
 	bigfile.c		\
 	cleanup.c		\
 	cltsrv.c		\
 	concur.c	    \
 	cvar.c			\
 	cvar2.c			\
 	dceemu.c		\
 	dlltest.c		\
+	dtoa.c			\
 	exit.c  		\
 	fileio.c		\
 	forktest.c	    \
 	fsync.c	        \
 	getproto.c		\
 	i2l.c		    \
 	inrval.c		\
 	intrupt.c       \
@@ -68,16 +69,17 @@ CSRCS =             \
 	lazyinit.c		\
 	lltest.c        \
 	lock.c          \
 	lockfile.c      \
 	logger.c		\
 	multiwait.c		\
 	many_cv.c		\
 	nbconn.c		\
+	nblayer.c		\
 	nonblock.c		\
 	op_2long.c      \
 	op_filnf.c		\
 	op_filok.c		\
 	op_noacc.c		\
 	op_nofil.c		\
 	parent.c    	\
 	perf.c    		\
@@ -92,27 +94,29 @@ CSRCS =             \
 	selct_er.c	    \
 	selct_nm.c	    \
 	selct_to.c	    \
 	select2.c  		\
 	sem.c 	  		\
 	servr_kk.c		\
 	servr_ku.c		\
 	servr_uk.c		\
+	short_thread.c	\
 	sigpipe.c		\
 	socket.c		\
 	sockopt.c		\
 	sprintf.c		\
 	sproc_ch.c	    \
 	sproc_p.c	    \
 	stdio.c		    \
 	strod.c			\
 	suspend.c		\
 	switch.c		\
 	system.c		\
+	testbit.c    	\
 	testfile.c    	\
 	threads.c 	  	\
 	thruput.c 	  	\
 	timemac.c		\
 	timetest.c		\
 	tmoacc.c        \
 	tmocon.c        \
 	tpd.c			\
@@ -404,25 +408,29 @@ LOGFILE = $(NSPR_TEST_LOGFILE)
 else
 ifeq ($(OS_ARCH), WINNT)
 LOGFILE = nul
 else
 LOGFILE = /dev/null
 endif
 endif
 
+ifeq ($(OS_TARGET),Linux)
+ECHO = /bin/echo
+endif
+
 ALWAYS:
 
 runtests:: $(PROGS) ALWAYS
 	@$(ECHO) "\nNSPR Test Results - $(OBJDIR)\n"
 	@$(ECHO) "BEGIN\t\t\t`date`"
 	@$(ECHO) "NSPR_TEST_LOGFILE\t$(LOGFILE)\n"
 	@$(ECHO) "Test\t\t\tResult\n"
 	@cd $(OBJDIR); for i in $(PROGRAMS); do					\
 	$(ECHO) "$$i\c";										\
 	./$$i >> $(LOGFILE) 2>&1 ;								\
 	if  [ 0 = $$? ] ; then									\
 		$(ECHO) "\t\t\tPassed";								\
 	else													\
 		$(ECHO) "\t\t\tFAILED";								\
-	fi														\
+	fi;														\
 	done
 	@$(ECHO) "\nEND\t\t`date`\n"
--- a/pr/tests/logger.c
+++ b/pr/tests/logger.c
@@ -29,16 +29,29 @@
 #include "prinrval.h"
 
 #include <stdio.h>
 
 #ifdef XP_MAC
 extern void SetupMacPrintfLog(char *logFile);
 #endif
 
+/* lth. re-define PR_LOG() */
+#if 0
+#undef PR_LOG_TEST
+#undef PR_LOG
+#define PR_LOG_TEST(_module,_level) ((_module)->level <= (_level))
+#define PR_LOG(_module,_level,_args)    \
+  {                                     \
+    if (PR_LOG_TEST(_module,_level))    \
+       PR_LogPrint _args   ;             \
+  }
+#endif
+
+
 static void Error(const char* msg)
 {
     printf("\t%s\n", msg);
 }  /* Error */
 
 static void PR_CALLBACK forked(void *arg)
 {
     PRIntn i;
@@ -60,16 +73,38 @@ static void PR_CALLBACK forked(void *arg
     
     PR_LogPrint("%s logging destroying condition variable\n", (const char*)arg);
     PR_DestroyCondVar(cv);
     PR_LogPrint("%s logging destroying mutex\n", (const char*)arg);
     PR_DestroyLock(ml);
     PR_LogPrint("%s forked thread exiting\n", (const char*)arg);
 }
 
+static void UserLogStuff( void )
+{
+    PRLogModuleInfo *myLM;
+    PRIntn i;
+
+    myLM = PR_NewLogModule( "userStuff" );
+    if (! myLM )
+      {
+        printf("UserLogStuff(): can't create new log module\n" );
+        return;
+      }
+
+    PR_LOG( myLM, PR_LOG_NOTICE, ("Log a Notice %d\n", 1 ));
+
+    for (i = 0; i < 10 ; i++ )
+      {
+        PR_LOG( myLM, PR_LOG_DEBUG, ("Log Debug number: %d\n", i));
+        PR_Sleep( 300 );
+      }
+
+} /* end UserLogStuff() */
+
 int main(PRIntn argc, const char **argv)
 {
     PRThread *thread;
     
     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
     PR_STDIO_INIT();
 
 #ifndef XP_MAC
@@ -89,16 +124,18 @@ int main(PRIntn argc, const char **argv)
     PR_LogPrint("%s logging into %s\n", argv[0], argv[1]);
 
     PR_LogPrint("%s creating new thread\n", argv[0]);
 	thread = PR_CreateThread(
 	    PR_USER_THREAD, forked, (void*)argv[0], PR_PRIORITY_NORMAL,
 	    PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
     PR_LogPrint("%s joining thread\n", argv[0]);
 
+    UserLogStuff();
+
     PR_JoinThread(thread);
 
     PR_LogFlush();
     return 0;
 
 exit:
     return -1;
 }
--- a/pr/tests/sleep.c
+++ b/pr/tests/sleep.c
@@ -20,20 +20,20 @@
 
 #if defined(XP_UNIX)
 
 #include <stdio.h>
 
 #include <unistd.h>
 #include <sys/time.h>
 
-#if defined(SOLARIS)
+#if defined(HAVE_SVID_GETTOD)
 #define GTOD(_a) gettimeofday(_a)
 #else
-#define GTOD(_a) gettimeofday(_a, NULL)
+#define GTOD(_a) gettimeofday((_a), NULL)
 #endif
 
 static PRIntn rv = 0;
 
 static void Other(void *unused)
 {
     PRIntn didit = 0;
     while (PR_SUCCESS == PR_Sleep(PR_MillisecondsToInterval(250)))
--- a/pr/tests/time.c
+++ b/pr/tests/time.c
@@ -82,17 +82,17 @@ static void timeGethrtime(void)
 #include <sys/time.h>
 static void timeGettimeofday(void)
 {
     PRInt32 index = count;
     time_t rv;
     struct timeval tp;
  
     for (;index--;)
-        rv = gettimeofday(&tp);
+        rv = gettimeofday(&tp, NULL);
 }
 
 static void timePRTime32(void)
 {
     PRInt32 index = count;
     PRInt32 rv32;
     PRTime q;
     PRTime rv;