PORT of OMNIORB 2.5.0 TO LYNXOS 2.5.1 ------------------------------------- Author: Neil Mason (GPT Limited) 2 PORT OF OMNIORB 2.5.0 Note all directories are relative to the top directory of the omniORB 2.5.0 build tree unless otherwise stated. 2.1 MAKEFILES The makefile structure for omniORB 2.5.0 is more complex than that for omniORB 2.2.0 but I imagine is easier to port as system dependencies are more clearly isolated. Each directory within the source tree contains the files GNUmakefile and dir.mk. GNUmakefile merely sets the variables TOP (indicates degree of nesting of the directory) and CURRENT (names the current directory) before calling config.mk. The GNUmakefile for the src directory is thus as follows: TOP=.. CURRENT=src include $(TOP)/config/config.mk The dir.mk file contains the directory specific make instructions. The dir.mk for the src directory is as follows: SUBDIRS += tool SUBDIRS += lib appl all:: @echo @echo 'No "all" rule here. If you want to build and export everything' @echo 'use "gnumake export". Otherwise build subdirectories separately.' @echo export:: @$(MakeSubdirs) clean:: rm -rf stub The file config.mk defines the platform for which the build is intended and includes the files ./mk/beforedir.mk, dir.mk and ./mk/afterdir.mk into the make. To build for a supported platform the only change that needs to be made is to uncomment the setting of the platform variable to the appropriate value [0.5.2]. For the port to LynxOS a new value of platform was added: # Coming into this file, the make variables TOP, CURRENT should have been # defined. # Uncomment one of the following platform line to build for the target # platform # # sun4_sosV_5.5 Solaris 2.x, Sunpro C++/gcc-2.7.2 # i586_linux_2.0 x86 Redhat linux 4.2, gcc-2.7.2 # alpha_osf1_3.2 Digital Unix 3.2, DEC C++ v5.5 # alpha_osf1_4.0 Digital Unix 4.0, DEC C++ v5.5 # powerpc_aix_4.2 IBM AIX 4.2, IBM C Set++ # hppa_hpux_10.20 HPUX 10.20, aC++ B3910B A.01.04 # x86_nt_3.5 Windows NT 3.5, MS VC++ 5.0 # x86_nt_4.0 Windows NT 4.0, MS VC++ 5.0 # x86_win95 Windows 95, MS VC++ 5.0 # i586_linux_2.0_egcs x86 Redhat linux 5.0, egcs-1.0+eh_patch # alpha_linux_2.0 alpha Redhat linux 5.0,egcs-1.0+eh_patch # powerpc_aix_4.2_egcs power PC AIX 4.2, egcs-1.0+eh_path # m68k_nextstep_3.3 NextStep 3.3, gcc-2.7.2 platform = sun4_sosV_5.5 #platform = i586_linux_2.0 #platform = alpha_osf1_3.2 #platform = alpha_osf1_4.0 #platform = powerpc_aix_4.2 #platform = hppa_hpux_10.20 #platform = x86_nt_3.5 #platform = x86_nt_4.0 #platform = x86_win95 #platform = i586_linux_2.0_egcs #platform = alpha_linux_2.0 #platform = powerpc_aix_4.2_egcs #platform = m68k_nextstep_3.3 # On Win32 platforms, uncomment the following line to build all the binaries # with debugging information. Useful if you want to debug the binaries under # MSVC developer's studio # #BuildDebugBinary = 1 # EXPORT_TREE = $(TOP) IMPORT_TREES = $(TOP) override VPATH := $(subst :, ,$(VPATH)) THIS_IMPORT_TREE := $(TOP) ifneq ($(wildcard $(THIS_IMPORT_TREE)/mk/beforedir.mk),) include $(THIS_IMPORT_TREE)/mk/beforedir.mk endif OMNIORB2_IDL_FPATH = $(TOP)/$(BINDIR)/$(OMNIORB2_IDL) include dir.mk THIS_IMPORT_TREE := $(TOP) ifneq ($(wildcard $(THIS_IMPORT_TREE)/mk/afterdir.mk),) include $(THIS_IMPORT_TREE)/mk/afterdir.mk endif The file beforedir.mk includes the platform specific makefile from the ./mk/platforms directory. For LynxOS a new platform specific make file x86_lynxOS_2.5.mk was created (the file has received minor editing to fit to line length): # **************************************************************************** # # Author : Neil Mason # Created : 20/03/98 # Description : make variables and rules specific to LynxOS 2.5 on # intel x86. # File Name : x86_lynxOS_2.5.mk # # History : 1.0 : 20/03/98 : Based on Hamish's version for omniORB v2.2.0 # : 1.1 : 23/03/98 : Added definition of LEX, CCP, and OMKDEPEND # : 1.1.1 : 24/03/98 : Ammended for use of cvup750 (mkdirhier) # : 1.2 : 26/03/98 : Added definition of CorbaImplementation, # OMNITHREAD_POSIX_CPPFLAGS, and ThreadSystem # (cvup175 version no longer up to date). # : 1.2.1 : 27/03/98 : Set debug flag to investigate failure of # omniNames # # Version : 1.3 # Date : 06/04/98 # Description : Use my version of mkdirhier which suppresses error messages # PLATFORM = x86_lynxOS_2.5 # NJM 20/03/98 LynxOS has pretensions of being a UNIX like OS - copied from # Solaris file # # Include general unix things # include $(THIS_IMPORT_TREE)/mk/unix.mk # NJM 20/03/98 Incorrect definitions should use those in beforedir.mk # LIBDIR = $(TOP)/lib # BINDIR = $(TOP)/bin # # C preprocessor macro definitions for this architecture # PLATFORM_CPPFLAGS = -D__lynxOS__ -D__i386 -D__i86__ -D__x86__ \ -D__OSVERSION__=205 -DUsePthread # # Standard programs # AR = ar cq RANLIB = ranlib # NJM 20/03/98 Use mkdirhier I copied from the SUN # NJM 24/03/98 Ammended for use on cvup750 # NJM 06/04/98 Use my version of mkdirhier which suppresses error messages MKDIRHIER = /home2/neilm/bin/mkdirhier CP = cp MV = mv -f RM = rm -f # NJM 20/03/98 Redefine INSTALL from unix.mk INSTALL = install -c # NJM 23/03/98 Seems to be no definition of LEX LEX = flex CXX = g++ # NJM 23/03/98 Added CXXMAKEDEPEND copied from i586_linux_2.0.mk CXXMAKEDEPEND = $(TOP)/$(BINDIR)/omkdepend -D__cplusplus -D__GNUG__ -D__GNUC__ # NJM 27/03/98 Added debug flag CXXDEBUGFLAGS = -g CXXOPTIONS = -fhandle-exceptions -Wall -Wno-unused -mthreads CXXFLAGS = $(CXXDEBUGFLAGS) $(CXXOPTIONS) $(CPPFLAGS) # CXXOPTIONS = -eh -D_MULTITHREAD CXXLINK = g++ CXXLINKOPTIONS = $(CXXDEBUGFLAGS) $(CXXOPTIONS) CPPFLAGS = $(DIR_CPPFLAGS) $(PLATFORM_CPPFLAGS) # NJM 20/03/98 Include this group for the definition of CLINK. COPTIONS # may not be right for LynxOS CC = gcc CMAKEDEPEND = $(TOP)/$(BINDIR)/omkdepend -D__GNUC__ CDEBUGFLAGS = -O COPTIONS = -fpcc-struct-return # NJM 23/03/98 Override the definition of CPP from unix.mk CPP = $(CXX) CLINK = $(CC) .SUFFIXES: .o .cc .C .cpp .cxx .cc.o: $(CXX) -c $(CXXFLAGS) -o $@ $< .C.o: $(CXX) -c $(CXXFLAGS) -o $@ $< .cpp.o: $(CXX) -c $(CXXFLAGS) -o $@ $< .cxx.o: $(CXX) -c $(CXXFLAGS) -o $@ $< # NJM 26/03/98 Include CorbaImplementation so CORBA.h is found CorbaImplementation = OMNIORB2 # NJM 26/03/98 Need POSIX version defined for use in posix.cc (copied # version number from Hamish OMNITHREAD_POSIX_CPPFLAGS = -DPthreadDraftVersion=4 OMNITHREAD_CPPFLAGS = -I$(TOP)/include -D_REENTRANT # NJM 26/03/98 Added in -lbsd to provide gethostbyname and inet_addr OMNITHREAD_LIB = -lomnithread -lbsd # OMNITHREAD_CPPFLAGS = $($(ThreadSystem)_OMNITHREAD_CPPFLAGS) # NJM 26/03/98 Need ThreadSystem defined to build libomnithread.a ThreadSystem = Posix # Default location of the omniORB2 configuration file [falls back to this if # the environment variable OMNIORB_CONFIG is not set] : # NJM 20/03/98 This directory no longer exists # OMNIORB_CONFIG_DEFAULT_LOCATION = \"/home1/hamishb/etc/omniORB.cfg\" OMNIORB_CPPFLAGS = -D__OMNIORB2__ $(OMNITHREAD_CPPFLAGS) OMNIORB_LIB = -lomniORB2 $(OMNITHREAD_LIB) -lbsd OMNIORB_STATIC_LIB = $(OMNIORB_LIB) #OMNIORB_STATIC_LIB = -Wl,-Bstatic -lomniORB2 -Wl,-Bdynamic \ # $(OMNITHREAD_STATIC_LIB) # Default directory for the omniNames log files. # NJM 20/03/98 This directory no longer exists # OMNINAMES_LOG_DEFAULT_LOCATION = \"/home1/hamishb/var/omninames\" The include relationship between the make files for a given directory is thus as follows: 2.2 INCLUDE FILE CHANGES The file values.h was copied from SUN cvsf367 to the directory ./src/tool/omniidl2/include to avoid an error in idl.yy stating that values.h was undefined. 2.3 SOURCE FILE CHANGES Some changes found necessary in porting omniORB 2.2.0 were reapplied: In posix.cc the following was added at the end of the include files: // NJM 02/04/98 Copied from Hamish #ifdef __lynxOS__ #include #endif In the same file in the method the stack size allocated for pthreads was increased and the call to pthread_attr_delete removed (this is actually not included in the Draft 4 standard) in the method omni_thread::start: #if defined(__osf1__) && defined(__alpha__) || defined(__VMS) // omniORB requires a larger stack size than the default (21120) // on OSF/1 THROW_ERRORS(pthread_attr_setstacksize(&attr, 32768)); // NJM 01/04/98 The stack size default for LynxOS is 16384, again less // than omniORB requires. Hamish seems to have had no problem with this. #elif defined (__lynxOS__) && (__i86__) THROW_ERRORS (pthread_attr_setstacksize (&attr, 32768)); #endif /* Stack size */ #if (PthreadDraftVersion == 4) THROW_ERRORS(pthread_create(&posix_thread, attr, omni_thread_wrapper, (void*)this)); // NJM 01/04/98 Note that the LynxOS documentation claims that // pthread_attr_delete does nothing and g++ warns that the statement has // no effect. // NJM 03/04/98 Removed from LynxOS since the statement has no effect #ifndef __LynxOS__ pthread_attr_delete(&attr); #endif In the same file in the method omni_thread::sleep: // NJM 02/04/98 Also applied to LynxOS as in Hamish's version #elif defined(__linux__) || defined(__aix__) || defined(__lynxOS__) if (secs > 2000) { sleep(secs); } else { usleep(secs * 1000000 + (nanosecs / 1000)); } In the same file in the method thread::get_time: // NJM 02/04/98 Also applies to LynxOS as in Hamish's version #if defined(__linux__) || defined(__aix__) || defined(__lynxOS__) struct timeval tv; // NJM 03/04/98 gettimeofday is not a POSIX function and usually doesn't // seem to have the second time zone parameter. gettimeofday(&tv, NULL); abs.tv_sec = tv.tv_sec; abs.tv_nsec = tv.tv_usec * 1000; 2.4 LYNXOS BUGS The following problems were found with the LynxOS Pthreads implementation: 1. In the routine pthread_cond_timedwait the timeout parameter seems to be relative. The manual page states that 'the timeout argument specifies the maximum amount of time to await the mutex lock’. The POSIX standard specifies this 'as an absolute time of day (rather than a relative time interval) so that the condition can be retested efficiently without recomputing the time-out value' [0.5.3]. Pthreads Programming [0.5.4] states that 'when the system time is greater than or equal to abstime, this function re-aquires the mutex and resumes its caller'. Giving an absolute time 30 seconds in the future pthread_cond_timedwait returns with errno 22 EINVAL (invalid argument). If the timeout is entered as 30 seconds this error is not returned. 2. POSIX specifies the return ETIME 'The time specified by abstime has passed'. This is not listed as a possible return in the LynxOS man page for pthread_cond_timedwait. 3. The LynxOS pthread_cond_timedwait returns EINTR (The wait was interrupted by a signal delivered to the thread) when called, apparently as a result of timing out. Colin Yuill says that he has received the same return from pthread_cond_wait. The LynxOS man page for both routines gives this as a possible return. Nichols et al [0.5.4] states that no pthreads functions return EINTR, and Kleiman et al [0.5.3] does not include EINTR in the valid returns from pthread_cond_wait and pthread_cond_timedwait. Note that omniORB version 2.2.0 contains calls to pthreads_cond_wait and pthreads_cond_timedwait but does not seem to encounter these problems. I have not investigated this further. The following changes were made to work round these problems: In ./appl/omniNames/omniNames.cc the call to omni_thread::get_time was replaced for LynxOS as follows: // NJM 15/04/98 LynxOS phtread_cond_timedwait is improperly implemented and // requires relative and not absolute time to wait #ifdef __lynxOS__ s = idle_time_btw_chkpt; n = 0; #else omni_thread::get_time(&s, &n, idle_time_btw_chkpt); #endif c.timedwait(s,n); In ./lib/omniORB2/scavenger.cc a similar change was made to make use of a relative timer. In the method inScavenger_t::run_undetached: // NJM 03/04/98 LynxOS seems to use relative time in pthread_cond_timedwait #ifndef __lynxOS__ unsigned long abs_sec,abs_nsec; omni_thread::get_time(&abs_sec,&abs_nsec,inScanPeriod); #endif if (inScanPeriod) { // NJM 03/04/98 Use relative time on LynxOS #ifdef __lynxOS__ int poke = pd_cond.timedwait (inScanPeriod); #else int poke = pd_cond.timedwait(abs_sec,abs_nsec); #endif In the method outScavenger_t::run_undetached: // NJM 03/04/98 LynxOS seems to use relative time in pthread_cond_timedwait #ifndef __lynxOS__ unsigned long abs_sec,abs_nsec; omni_thread::get_time(&abs_sec,&abs_nsec,outScanPeriod); #endif if (outScanPeriod) { // NJM 03/04/98 Use relative time on LynxOS #ifdef __lynxOS__ int poke = pd_cond.timedwait (outScanPeriod); #else int poke = pd_cond.timedwait(abs_sec,abs_nsec); #endif In the file posix.cc in the method omni_condition::wait: // NJM 07/04/98 Colin Yuill says that this call can give incorrect error // returns on LynxOS so protect against them. #ifdef __lynxOS__ int rc = EINTR; while (rc == EINTR) rc = ERRNO(pthread_cond_wait(&posix_cond, &mutex->posix_mutex)); #else THROW_ERRORS(pthread_cond_wait(&posix_cond, &mutex->posix_mutex)); #endif In the method omni_condition::timedwait: // NJM 07/04/98 According to the POSIX standard only certain specific // routines may return EINTR. pthread_cond_timedwait is not one of them. The // LynxOS man page lists this as a possible error return and I seem to be // getting it. Colin Yuill has had similar problems with pthread_cond_wait. // He suggests use of a while loop to recall. #ifdef __lynxOS__ int rc = EINTR; while (rc == EINTR) rc = ERRNO(pthread_cond_timedwait(&posix_cond, &mutex->posix_mutex, &rqts)); #else int rc = ERRNO(pthread_cond_timedwait(&posix_cond, &mutex->posix_mutex, &rqts)); #endif // __lynxOS End of section