Merged Neutrino (NTO) changes contributed by Jerry L. Kirk
authorwtc%netscape.com
Mon, 28 Jun 1999 23:13:18 +0000
changeset 676 91c3ca38b198ca3c695fd0c7bd92b6d1bbd4c468
parent 675 36476d72f944f746ccbcfad45cea120053b0a3c2
child 677 1cc363f0bf5f392f146b0bfce840c2616d31831a
push idunknown
push userunknown
push dateunknown
Merged Neutrino (NTO) changes contributed by Jerry L. Kirk <Jerry.Kirk@Nexwarecorp.com>. Modified files: pr/include/md/Makefile, _pth.h, prosdep.h, pr/src/md/unix/Makefile, objs.mk, unix.c, unix_errors.c, ptio.c, ptthread.c. Added files: NTO.mk, _nto.cfg, _nto.h, nto.c.
config/NTO.mk
pr/include/md/Makefile
pr/include/md/_nto.cfg
pr/include/md/_nto.h
pr/include/md/_pth.h
pr/include/md/prosdep.h
pr/src/md/unix/Makefile
pr/src/md/unix/nto.c
pr/src/md/unix/objs.mk
pr/src/md/unix/unix.c
pr/src/md/unix/unix_errors.c
pr/src/pthreads/ptio.c
pr/src/pthreads/ptthread.c
new file mode 100644
--- /dev/null
+++ b/config/NTO.mk
@@ -0,0 +1,51 @@
+#
+# The contents of this file are subject to the Netscape Public License
+# Version 1.1 (the "NPL"); you may not use this file except in
+# compliance with the NPL.  You may obtain a copy of the NPL at
+# http://www.mozilla.org/NPL/
+# 
+# Software distributed under the NPL is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+# for the specific language governing rights and limitations under the
+# NPL.
+# 
+# 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.
+#
+
+######################################################################
+# Config stuff for Neutrino
+######################################################################
+
+include $(MOD_DEPTH)/config/UNIX.mk
+
+CPU_ARCH	 = x86
+AR			 = qcc -Vgcc_ntox86 -M -a $@
+CC			 = qcc -Vgcc_ntox86 -shared 
+LD			 = $(CC)
+CCC			 = $(CC)
+OS_CFLAGS	 = -Wc,-Wall -Wc,-Wno-parentheses -DNTO -DNTO2 -Di386 \
+			   -D_QNX_SOURCE -DNO_REGEX \
+			   -DSTRINGS_ALIGNED -D__i386__ -D__QNXNTO__ -DPIC \
+			   -DHAVE_POINTER_LOCALTIME_R
+COMPILER_TAG = _qcc
+MKSHLIB		 = qcc -Vgcc_ntox86 -shared -Wl,-h$(@:$(OBJDIR)/%.so=%.so) -g2 -M
+
+RANLIB		 = ranlib
+G++INCLUDES	 =
+OS_LIBS		 =
+XLDOPTS		 =
+
+ifdef USE_PTHREADS
+	IMPL_STRATEGY	= _PTH
+else
+	IMPL_STRATEGY   = _EMU
+endif
+
+NOSUCHFILE	= /no-such-file
+
+GARBAGE		= $(wildcard *.err)
+
+	
\ No newline at end of file
--- a/pr/include/md/Makefile
+++ b/pr/include/md/Makefile
@@ -134,16 +134,20 @@ endif
 ifeq ($(OS_ARCH),DGUX)
 MDCPUCFG_H = _dgux.cfg
 endif
 
 ifeq ($(OS_ARCH),QNX)
 MDCPUCFG_H = _qnx.cfg
 endif
 
+ifeq ($(OS_ARCH),NTO)
+MDCPUCFG_H = _nto.cfg
+endif
+
 ifeq ($(OS_ARCH),BeOS)
 MDCPUCFG_H = _beos.cfg
 endif
 
 export:: $(MDCPUCFG_H)
 	$(INSTALL) -m 444 $(MDCPUCFG_H) $(DIST)/include
 ifeq ($(MOZ_BITS),16)
 	cp $(DIST)/include/$(MDCPUCFG_H) $(DIST)/include/prcpucfg.h
new file mode 100644
--- /dev/null
+++ b/pr/include/md/_nto.cfg
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * 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.
+ */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NTO
+#define NTO
+#endif
+
+#ifdef __i386__
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1L
+#define PR_BYTES_PER_SHORT  2L
+#define PR_BYTES_PER_INT    4L
+#define PR_BYTES_PER_INT64  8L
+#define PR_BYTES_PER_LONG   4L
+#define PR_BYTES_PER_FLOAT  4L
+#define PR_BYTES_PER_DOUBLE 8L
+#define PR_BYTES_PER_WORD   4L
+#define PR_BYTES_PER_DWORD  8L
+
+#define PR_BITS_PER_BYTE    8L
+#define PR_BITS_PER_SHORT   16L
+#define PR_BITS_PER_INT     32L
+#define PR_BITS_PER_INT64   64L
+#define PR_BITS_PER_LONG    32L
+#define PR_BITS_PER_FLOAT   32L
+#define PR_BITS_PER_DOUBLE  64L
+#define PR_BITS_PER_WORD    32L
+
+#define PR_BITS_PER_BYTE_LOG2   3L
+#define PR_BITS_PER_SHORT_LOG2  4L
+#define PR_BITS_PER_INT_LOG2    5L
+#define PR_BITS_PER_INT64_LOG2  6L
+#define PR_BITS_PER_LONG_LOG2   5L
+#define PR_BITS_PER_FLOAT_LOG2  5L
+#define PR_BITS_PER_DOUBLE_LOG2 6L
+#define PR_BITS_PER_WORD_LOG2   5L
+
+#define PR_ALIGN_OF_SHORT   2L
+#define PR_ALIGN_OF_INT     4L
+#define PR_ALIGN_OF_LONG    4L
+#define PR_ALIGN_OF_INT64   4L
+#define PR_ALIGN_OF_FLOAT   4L
+#define PR_ALIGN_OF_DOUBLE  4L
+#define PR_ALIGN_OF_POINTER 4L
+#define PR_ALIGN_OF_WORD    4L
+
+#define PR_BYTES_PER_WORD_LOG2   2L
+#define PR_BYTES_PER_DWORD_LOG2  3L
+#define PR_WORDS_PER_DWORD_LOG2  1L
+
+#else
+
+#error Undefined CPU Architecture
+
+#endif
+
+#define HAVE_LONG_LONG
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
new file mode 100644
--- /dev/null
+++ b/pr/include/md/_nto.h
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * 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.
+ */
+
+#ifndef nspr_nto_defs_h___
+#define nspr_nto_defs_h___
+
+/*
+** Internal configuration macros
+*/
+#define PR_LINKER_ARCH		"nto"
+#define _PR_SI_SYSNAME		"NTO"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS		MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef  _PR_POLL_AVAILABLE
+#undef  _PR_USE_POLL
+#define _PR_HAVE_SOCKADDR_LEN
+#undef  HAVE_BSD_FLOCK
+#define HAVE_FCNTL_FILE_LOCKING
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#include <sys/select.h>
+
+#undef  HAVE_STACK_GROWING_UP
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR
+#endif
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP			setjmp
+#define _LONGJMP		longjmp
+#define _PR_CONTEXT_TYPE	jmp_buf
+#define _PR_NUM_GCREGS		_JBLEN
+#define _MD_GET_SP(_t)		(_t)->md.context[7]
+
+#define CONTEXT(_th)		((_th)->md.context)
+
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	\
+{							\
+    *status = PR_TRUE;					\
+    if(_SETJMP(CONTEXT(_thread))) (*_main)();		\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128);		\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)	\
+    if (!_SETJMP(CONTEXT(_thread))) {	\
+	(_thread)->md.errcode = errno;	\
+	_PR_Schedule();			\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)	\
+{					\
+    errno = (_thread)->md.errcode;	\
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    _LONGJMP(CONTEXT(_thread), 1);	\
+}
+
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** md-specific cpu structure field
+*/
+#define _PR_MD_MAX_OSFD		FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu)	PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock)		PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_GET_INTERVAL		_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC		_PR_UNIX_TicksPerSecond
+#define _MD_EARLY_INIT			_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+** We wrapped the select() call.  _MD_SELECT refers to the built-in,
+** unwrapped version.
+*/
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#define _MD_SELECT		select
+
+#endif /* nspr_nto_defs_h___ */
--- a/pr/include/md/_pth.h
+++ b/pr/include/md/_pth.h
@@ -88,17 +88,17 @@
 #if defined(_PR_DCETHREADS)
 #define PTHREAD_ZERO_THR_HANDLE(t)        memset(&(t), 0, sizeof(pthread_t))
 #define PTHREAD_THR_HANDLE_IS_ZERO(t) \
 	(!memcmp(&(t), &pt_zero_tid, sizeof(pthread_t)))
 #define PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
 #elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(SOLARIS) \
 	|| defined(HPUX) || defined(LINUX) || defined(FREEBSD) \
 	|| defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \
-	|| defined(VMS)
+	|| defined(VMS) || defined(NTO)
 #define PTHREAD_ZERO_THR_HANDLE(t)        (t) = 0
 #define PTHREAD_THR_HANDLE_IS_ZERO(t)     (t) == 0
 #define PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
 #else 
 #error "pthreads is not supported for this architecture"
 #endif
 
 #if defined(_PR_DCETHREADS)
@@ -181,16 +181,24 @@
 #include <sys/sched.h>
 #define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
 #define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
 #endif /* defined(_PR_DCETHREADS) */
 
 #elif defined(LINUX)
 #define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
 #define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
+#elif defined(NTO)
+/*
+ * Neutrino has functions that return the priority range but
+ * they return invalid numbers, so I just hard coded these here
+ * for now.  Jerry.Kirk@Nexarecorp.com
+ */
+#define PT_PRIO_MIN            0
+#define PT_PRIO_MAX            30 
 #elif defined(SOLARIS)
 /*
  * Solaris doesn't seem to have macros for the min/max priorities.
  * The range of 0-127 is mentioned in the pthread_setschedparam(3T)
  * man pages, and pthread_setschedparam indeed allows 0-127.  However,
  * pthread_attr_setschedparam does not allow 0; it allows 1-127.
  */
 #define PT_PRIO_MIN            1
@@ -224,15 +232,15 @@ extern int (*_PT_aix_yield_fcn)();
 #define PTHREAD_YIELD() \
     PR_BEGIN_MACRO               				\
 		struct timespec onemillisec = {0};		\
 		onemillisec.tv_nsec = 1000000L;			\
         nanosleep(&onemillisec,NULL);			\
     PR_END_MACRO
 #elif defined(HPUX) || defined(LINUX) || defined(SOLARIS) \
 	|| defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
-	|| defined(BSDI)
+	|| defined(BSDI) || defined(NTO)
 #define PTHREAD_YIELD()            	sched_yield()
 #else
 #error "Need to define PTHREAD_YIELD for this platform"
 #endif
 
 #endif /* nspr_pth_defs_h_ */
--- a/pr/include/md/prosdep.h
+++ b/pr/include/md/prosdep.h
@@ -111,16 +111,19 @@ PR_BEGIN_EXTERN_C
 #include "md/_dgux.h"
 
 #elif defined(QNX)
 #include "md/_qnx.h"
 
 #elif defined(VMS)
 #include "md/_openvms.h"
 
+#elif defined(NTO)
+#include "md/_nto.h"
+
 #else
 #error unknown Unix flavor
 
 #endif
 
 #include "md/_unixos.h"
 #include "md/_unix_errors.h"
 
--- a/pr/src/md/unix/Makefile
+++ b/pr/src/md/unix/Makefile
@@ -121,16 +121,20 @@ SCOOS_CSRCS = \
 DGUX_CSRCS = \
 	dgux.c \
 	$(NULL)
 
 QNX_CSRCS = \
 	qnx.c \
 	$(NULL)
 
+NTO_CSRCS = \
+	nto.c \
+	$(NULL)
+
 ifeq ($(PTHREADS_USER),1)
 CSRCS += $(PTH_USER_CSRCS)
 endif
 
 ifeq ($(OS_ARCH),IRIX)
 CSRCS += $(IRIX_CSRCS)
 endif
 
@@ -192,18 +196,22 @@ CSRCS += $(NCR_CSRCS)
 endif
 ifeq ($(OS_ARCH),SCOOS)
 CSRCS += $(SCOOS_CSRCS)
 endif
 ifeq ($(OS_ARCH),DGUX)
 CSRCS += $(DGUX_CSRCS)
 endif
 ifeq ($(OS_ARCH),QNX)
+ifeq ($(OS_TARGET),NTO)
+CSRCS += $(NTO_CSRCS)
+else
 CSRCS += $(QNX_CSRCS)
 endif
+endif
 
 #
 # Some Unix platforms have an assembly language file.
 # E.g., AIX 3.2, Solaris (both sparc and x86).
 #
 ifeq ($(OS_ARCH), AIX)
     ifeq ($(OS_RELEASE), 3.2)
 	ASFILES   = os_$(OS_ARCH).s
new file mode 100644
--- /dev/null
+++ b/pr/src/md/unix/nto.c
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * 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"
+
+#include <setjmp.h>
+
+/* Fake this out */
+int socketpair (int foo, int foo2, int foo3, int sv[2])
+{
+	printf("error in socketpair\n");
+	exit (-1);
+}
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+    (void) setjmp(CONTEXT(t));
+    }
+
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
--- a/pr/src/md/unix/objs.mk
+++ b/pr/src/md/unix/objs.mk
@@ -113,16 +113,19 @@ SCOOS_CSRCS = \
 DGUX_CSRCS = \
 	dgux.c \
 	$(NULL)
 
 QNX_CSRCS = \
 	qnx.c \
 	$(NULL)
 
+NTO_CSRCS = \
+	nto.c \
+	$(NULL)
 
 ifeq ($(PTHREADS_USER),1)
 CSRCS += $(PTH_USER_CSRCS)
 endif
 
 ifeq ($(OS_ARCH),IRIX)
 CSRCS += $(IRIX_CSRCS)
 endif
@@ -185,18 +188,22 @@ CSRCS += $(NCR_CSRCS)
 endif
 ifeq ($(OS_ARCH),SCOOS)
 CSRCS += $(SCOOS_CSRCS)
 endif
 ifeq ($(OS_ARCH),DGUX)
 CSRCS += $(DGUX_CSRCS)
 endif
 ifeq ($(OS_ARCH),QNX)
+ifeq ($(OS_TARGET),NTO)
+CSRCS += $(NTO_CSRCS)
+else
 CSRCS += $(QNX_CSRCS)
 endif
+endif
  
 #
 # Some Unix platforms have an assembly language file.
 # E.g., AIX 3.2, Solaris (both sparc and x86).
 #
 ifeq ($(OS_ARCH), AIX)
     ifeq ($(OS_RELEASE), 3.2)
 	ASFILES   = os_$(OS_ARCH).s
--- a/pr/src/md/unix/unix.c
+++ b/pr/src/md/unix/unix.c
@@ -47,17 +47,17 @@
 #elif defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \
     || defined(AIX4_1) || defined(LINUX) || defined(SONY) \
     || defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \
     || defined(SUNOS4) || defined(NCR) || defined(RHAPSODY) \
     || defined(NEXTSTEP) || defined(QNX)
 #define _PRSockLen_t int
 #elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
     || defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \
-    || defined(DGUX) || defined(VMS)
+    || defined(DGUX) || defined(VMS) || defined(NTO)
 #define _PRSockLen_t size_t
 #else
 #error "Cannot determine architecture"
 #endif
 
 /*
 ** Global lock variable used to bracket calls into rusty libraries that
 ** aren't thread safe (like libc, libX, etc).
@@ -3415,17 +3415,61 @@ void PR_XNotify(void)
     PR_Notify(_pr_Xfe_mon);
 }
 
 void PR_XNotifyAll(void)
 {
     PR_NotifyAll(_pr_Xfe_mon);
 }
 
-#ifdef HAVE_BSD_FLOCK
+#if defined(HAVE_FCNTL_FILE_LOCKING)
+
+PR_IMPLEMENT(PRStatus)
+_MD_LockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_WRLCK;
+    rv = fcntl(f, F_SETLKW, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_TLockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_WRLCK;
+    rv = fcntl(f, F_SETLK, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_UnlockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_UNLCK;
+    rv = fcntl(f, F_SETLK, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+#elif defined(HAVE_BSD_FLOCK)
 
 #include <sys/file.h>
 
 PR_IMPLEMENT(PRStatus)
 _MD_LockFile(PRInt32 f)
 {
     PRInt32 rv;
     rv = flock(f, LOCK_EX);
--- a/pr/src/md/unix/unix_errors.c
+++ b/pr/src/md/unix/unix_errors.c
@@ -37,17 +37,20 @@ static void _MD_unix_map_default_error(i
             prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
             break;
         case EAFNOSUPPORT:
             prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
             break;
         case EAGAIN:
             prError = PR_WOULD_BLOCK_ERROR;
             break;
-#ifndef QNX
+        /*
+         * On QNX and Neutrino, EALREADY is defined as EBUSY.
+         */
+#if EALREADY != EBUSY
         case EALREADY:
             prError = PR_ALREADY_INITIATED_ERROR;
             break;
 #endif
         case EBADF:
             prError = PR_BAD_DESCRIPTOR_ERROR;
             break;
 #ifdef EBADMSG
--- a/pr/src/pthreads/ptio.c
+++ b/pr/src/pthreads/ptio.c
@@ -118,31 +118,32 @@ static ssize_t (*pt_aix_sendfile_fptr)()
 /* On Alpha Linux, these are already defined in sys/socket.h */
 #if !(defined(LINUX) && defined(__alpha))
 #include <netinet/tcp.h>  /* TCP_NODELAY, TCP_MAXSEG */
 #endif
 
 #if defined(SOLARIS)
 #define _PRSockOptVal_t char *
 #elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(HPUX) \
-    || defined(LINUX) || defined(FREEBSD) || defined(BSDI) || defined(VMS)
+    || defined(LINUX) || defined(FREEBSD) || defined(BSDI) || defined(VMS) \
+    || defined(NTO)
 #define _PRSockOptVal_t void *
 #else
 #error "Cannot determine architecture"
 #endif
 
 #if (defined(HPUX) && !defined(HPUX10_30) && !defined(HPUX11))
 #define _PRSelectFdSetArg_t int *
 #elif defined(AIX4_1)
 #define _PRSelectFdSetArg_t void *
 #elif defined(IRIX) || (defined(AIX) && !defined(AIX4_1)) \
     || defined(OSF1) || defined(SOLARIS) \
     || defined(HPUX10_30) || defined(HPUX11) || defined(LINUX) \
     || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
-    || defined(BSDI) || defined(VMS)
+    || defined(BSDI) || defined(VMS) || defined(NTO)
 #define _PRSelectFdSetArg_t fd_set *
 #else
 #error "Cannot determine architecture"
 #endif
 
 static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type);
 
 static PRLock *_pr_flock_lock;  /* For PR_LockFile() etc. */
@@ -2809,17 +2810,17 @@ static PRIOMethods _pr_socketpollfd_meth
 };
 
 #if defined(_PR_FCNTL_FLAGS)
 #undef _PR_FCNTL_FLAGS
 #endif
 
 #if defined(HPUX) || defined(OSF1) || defined(SOLARIS) || defined (IRIX) \
     || defined(AIX) || defined(LINUX) || defined(FREEBSD) || defined(NETBSD) \
-    || defined(OPENBSD) || defined(BSDI) || defined(VMS)
+    || defined(OPENBSD) || defined(BSDI) || defined(VMS) || defined(NTO)
 #define _PR_FCNTL_FLAGS O_NONBLOCK
 #else
 #error "Can't determine architecture"
 #endif
 
 static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type)
 {
     PRInt32 flags, one = 1;
--- a/pr/src/pthreads/ptthread.c
+++ b/pr/src/pthreads/ptthread.c
@@ -57,18 +57,27 @@ static struct _PT_Bookeeping
 } pt_book = {0};
 
 static void _pt_thread_death(void *arg);
 static void init_pthread_gc_support(void);
 
 #if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
 static PRIntn pt_PriorityMap(PRThreadPriority pri)
 {
+#ifdef NTO
+    /* This priority algorithm causes lots of problems on Neutrino
+     * for now I have just hard coded everything to run at priority 10
+     * until I can come up with a new algorithm.
+     *     Jerry.Kirk@Nexwarecorp.com
+     */
+    return 10;
+#else
     return pt_book.minPrio +
 	    pri * (pt_book.maxPrio - pt_book.minPrio) / PR_PRIORITY_LAST;
+#endif
 }
 #endif
 
 /*
 ** Initialize a stack for a native pthread thread
 */
 static void _PR_InitializeStack(PRThreadStack *ts)
 {
@@ -266,16 +275,20 @@ static PRThread* _PR_CreateThread(
         rv = pthread_attr_setprio(&tattr, pt_PriorityMap(priority));
         PR_ASSERT(0 == rv);
 #elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
         rv = pthread_attr_getschedparam(&tattr, &schedule);
         PR_ASSERT(0 == rv);
         schedule.sched_priority = pt_PriorityMap(priority);
         rv = pthread_attr_setschedparam(&tattr, &schedule);
         PR_ASSERT(0 == rv);
+#ifdef NTO
+        rv = pthread_attr_setschedpolicy(&tattr, SCHED_RR); /* Round Robin */
+        PR_ASSERT(0 == rv);
+#endif
 #endif /* !defined(_PR_DCETHREADS) */
     }
 
     /*
      * DCE threads can't set detach state before creating the thread.
      * AIX can't set detach late. Why can't we all just get along?
      */
 #if !defined(_PR_DCETHREADS)