m4_comment([$Id: port.so,v 10.5 2006/08/24 16:32:28 bostic Exp $]) m4_ref_title(Distribution, Porting m4_db to new architectures,, test/faq, distrib/layout) m4_p([dnl m4_db is generally easy to port to new architectures. m4_db was designed to be as portable as possible, and has been ported to a wide variety of systems, from Wind River's Tornado system, to VMS, to Windows/NT and Windows/95, and most existing UNIX platforms. It runs on 16, 32 and 64-bit machines, little or big-endian. The difficulty of a port depends on how much of the ANSI C and POSIX 1003.1 standards the new architecture offers.]) m4_p([dnl An abstraction layer separates the main m4_db code from the operating system and architecture specific components. This layer is comprised of approximately 2500 lines of C language code, found in the m4_path(os) subdirectory of the m4_db distribution. The following list of files include functionality that may need to be modified or implemented in order to support a new architecture. Within each file, there is usually one, but sometimes several functions (for example, the m4_path(os_alloc.c) file contains the malloc, calloc, realloc, free, and strdup functions).]) m4_table_begin(, _center) m4_table_header(Source file, Description) m4_table_element(os_abs.c, [Return if a filename is an absolute pathname]) m4_table_element(os_alloc.c, [ANSI C malloc, calloc, realloc, strdup, free front-ends]) m4_table_element(os_clock.c, [Return the current time-of-day]) m4_table_element(os_config.c, [Return run-time configuration information]) m4_table_element(os_dir.c, [Read the filenames from a directory]) m4_table_element(os_errno.c, [Set/get the ANSI C errno value]) m4_table_element(os_fid.c, [Create a unique ID for a file]) m4_table_element(os_fsync.c, [POSIX 1003.1 fsync front-end]) m4_table_element(os_handle.c, [Open file handles]) m4_table_element(os_id.c, [Return thread ID]) m4_table_element(os_map.c, [Map a shared memory area]) m4_table_element(os_method.c, [Run-time replacement of system calls]) m4_table_element(os_oflags.c, [Convert POSIX 1003.1 open flags, modes to m4_db flags]) m4_table_element(os_open.c, [Open file handles]) m4_table_element(os_region.c, [Map a shared memory area]) m4_table_element(os_rename.c, [POSIX 1003.1 rename call]) m4_table_element(os_root.c, [Return if application has special permissions]) m4_table_element(os_rpath.c, [Return last pathname separator]) m4_table_element(os_rw.c, [POSIX 1003.1 read/write calls]) m4_table_element(os_seek.c, [POSIX 1003.1 seek call]) m4_table_element(os_sleep.c, [Cause a thread of control to release the CPU]) m4_table_element(os_spin.c, [Return the times to spin while waiting for a mutex]) m4_table_element(os_stat.c, [POSIX 1003.1 stat call]) m4_table_element(os_tmpdir.c, [Set the path for temporary files]) m4_table_element(os_unlink.c, [POSIX 1003.1 unlink call]) m4_table_end m4_p([dnl All but a few of these files contain relatively trivial pieces of code. Typically, there is only a single version of the code for all platforms m4_db supports, and that code lives in the m4_path(os) directory of the distribution. Where different code is required, the code is either conditionally compiled or an entirely different version is written. For example, VxWorks versions of some of these files can be found in the distribution directory os_vxworks, and Windows versions can be found in os_windows.]) m4_p([dnl Historically, there are only two difficult questions to answer for each new port. The first question is how to handle shared memory. In order to write multiprocess database applications (not multithreaded, but threads of control running in different address spaces), m4_db must be able to name pieces of shared memory and access them from multiple processes. On UNIX/POSIX systems, we use m4_bold(mmap) and m4_bold(shmget) for that purpose, but any interface that provides access to named shared memory is sufficient. If you have a simple, flat address space, you should be able to use the code in m4_path(os_vxworks/os_map.c) as a starting point for the port. If you are not intending to write multiprocess database applications, then this won't be necessary, as m4_db can simply allocate memory from the heap if all threads of control will live in a single address space.]) m4_p([dnl The second question is mutex support. m4_db requires some form of m4_bold([self-blocking]) mutual exclusion mutex. Blocking mutexes are preferred as they tend to be less CPU-expensive and less likely to cause thrashing. If blocking mutexes are not available, however, test-and-set will work as well. The code for mutexes is in two places in the system: the include file m4_path(dbinc/mutex.h), and the distribution directory m4_path(mutex).]) m4_p([dnl m4_db uses the GNU autoconf tools for configuration on almost all of the platforms it supports. Specifically, the include file m4_path(db_config.h) configures the m4_db build. The simplest way to begin a port is to configure and build m4_db on a UNIX or UNIX-like system, and then take the m4_path(Makefile) and m4_path(db_config.h) file created by that configuration, and modify it by hand to reflect the needs of the new architecture. Unless you're already familiar with the GNU autoconf toolset, we don't recommend you take the time to integrate your changes back into the m4_db autoconfiguration framework. Instead, send us context diffs of your changes and any new source files you created, and we'll integrate the changes into our source tree.]) m4_p([dnl Finally, we're happy to work with you on the port, or potentially, do the port ourselves, if that is of interest to you. Regardless, if you have any porting questions, just let us know, and we will be happy to answer them.]) m4_page_footer