The startup procedure that initializes the eXtremeDB runtime environment in C applications is
mco_runtime_start()
. It must be called before any database operations can be performed. However, prior to callingmco_runtime_start()
, it is common practice to register a fatal error handler by callingmco_error_set_handler()
and in some special cases it may be necessary to set runtime options by callingmco_runtime_setoption()
. The functionmco_get_runtime_info()
can be called any time after initialization to obtain the specific configuration details of the current runtime. Then, when finished with database activity (after disconnecting from and closing all databases), C applications must callmco_runtime_stop()
to clean up semaphores and perform an orderly shutdown of the runtime.The typical sequence of API calls would look like the following:
static void errhandler(MCO_RET n) { printf("\neXtremeDB runtime fatal error: %d", n); getchar(); exit( 0 ); } int main(int argc, char* argv[]) { MCO_RET rc; mco_db_h db; mco_error_set_handler(&errhandler); mco_runtime_start(); // Perform database processing mco_runtime_stop(); }
Runtime Options
There are a small number of per-process global database runtime options to manage shared memory operating system parameters and other special features. These options are set by calling
mco_runtime_setoption()
prior to runtime initialization and can be retrieved at any time prior to runtime shutdown by callingmco_runtime_getoption()
. (Please refer to the Reference Guide pagemco_runtime_setoption()
for the list of actual runtime options.)For example a multi-process shared memory application on a Unix system may need to set the shared memory access mode from the default value of
0666
. To do so the application would set this runtime option with code like the following.mco_runtime_setoption( MCO_RT_OPTION_UNIX_SHM_MASK, 0600 ); ... mco_runtime_start(); ...Persistent Databases
The runtime options for persistent database applications are the same as for in-memory database applications, however there are important memory device definitions and database open parameters that must be specified for persistent databases. (Please use these links for detailed explanations.)
Runtime Libraries
At a minimum, In-Memory database applications must link with the following basic eXtremeDB libraries:
1.
mcolib
: basic core runtime functions2.
mcovtmem
: “virtual table” memory manager functions3.
mcotmursiw
,mcotmvcc
ormcotexcl
: Transaction Manager functions4.
mcomconv
,mcomipc
,mcompsx
, ormcomw32
: memory devices functions5. synchronization library: functions that synchronize access to database objects as well as internal runtime structures (see below)
6.
mcouwrt
ormcowrt
: utility functionsPersistent Databases
Whereas In-Memory database applications use the “virtual tables” library
mcovtmem
, persistent database applications use librarymcovtdsk
and a file system library:Applications that use the eXtremeDB
mco_db_save()
ormco_db_load()
functions to store and retrieve database image files to or from persistent media, require serialization and file system functions that are provided in themcoseri
library. (Please refer to the runtime libraries reference guide page for further details and examples.)Synchronization Libraries
The database repository and the database runtime metadata are shared resources. They are read and written by multiple tasks at a time. To ensure the correctness of internal structures and repository data, the eXtremeDB runtime must make sure that those read and write operations are executed in proper order. In other words, access to them must be “synchronized”. For most supported platforms, two synchronization methods are provided. One is based solely on the operating system’s synchronization kernel primitive, such as semaphores. The other method combines atomic instructions with OS synchronization primitives.
A locking algorithm can create a user-space “fast path” by first attempting to lock the resource using an atomic instruction. If the attempt fails, and a thread needs to block, a system call is then executed. But if there is no contention (as is often the case) the kernel doesn't need to be notified. Kernel calls are relatively expensive because they lead to CPU context switching and other activity. So where atomic operations are possible, they provide significant performance advantages.
These synchronization methods are implemented in the synchronization libraries. All applications, except possibly single-threaded applications (see comment on
mcosempty.c
below) must link with one of the synchronization libraries listed in the package contents by operating system. Where possible, a version of the library is provided that uses “atomic operations” to avoid unnecessary kernel calls.Most applications, particularly single-threaded or multi-threaded applications with low database activity (on the order of one database update per second), can benefit greatly by using the “+ atomic op.” library if available. But there is no universal general rule. Many factors determine whether the “+ atomic op.” library will work, such as: the application’s database access pattern and rate, the kernel’s scheduler policy, and even hardware.
Where two versions of the synchronization library are provided, the same version must be used by all applications. When more than one application will be accessing the database, or in multi-platform scenarios where database access may be incorporated in different application modules written in C, C++, C# or Java, it is important that all application modules are linked with the same synchronization library.
The file
mcosempty.c
contains a “hollow” synchronization implementation that can be compiled on any platform. It has no synchronization code, so it is the fastest implementation - but it is valid for single-threaded applications only. If this source file is included in the application build, then no synchronization library is necessary.The most commonly used synchronization libraries are:
(Again, please refer to the package contents for platform-specific details.)
Direct Pointer Libraries
As mentioned in the Product Overview, eXtremeDB provides two versions of runtime libraries for all-in-memory databases: the optimized “Direct Pointer Arithmetic” version and the “Offset” version. The advantages of the “Offset” libraries are A) that a saved binary image of an in-memory database can be loaded to a different starting address in memory, and, B) two (or more) applications that share an in-memory database in shared memory do not have to map the shared memory segment to the same address space in their local process (which is sometimes impossible). The advantage of the Direct Pointer Arithmetic library is better performance, and is ideal for in-memory databases within a single (possibly multi-threaded) process.
In eXtremeDB packages prior to version 7.1, the package was specifically built for Direct Pointer or for Offset support. For eXtremeDB version 7.1 and later all packages include two versions of the runtime libraries. The Offset version is the default and this version of the runtime libraries is located in directories
eXtremeDB/target/bin
andeXtremeDB/target/bin.so
. The Direct Pointer version of the libraries is located in directorieseXtremeDB/target/bin.dptr
andeXtremeDB/target/bin.dptr.so
.When building applications on Unix-Linux systems, the make command line option
PRJ_DIRECTPTR=YES
can be used to cause linking with the Direct Pointer libraries. On Windows, applications are generally developed with Visual Studio which does not have a convenient command line option. So to link with the Direct Pointer libraries, project settings must be properly set to theeXtremeDB/target/bin.dptr
oreXtremeDB/target/bin.dptr.so
directories.