# Runtime Control in C

> 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 calling `mco_runtime_start()`, it is common practice to register a fatal error handler by calling `mco_error_set_handler()`and in some special cases it may be necessary to set runtime options by calling `mco_runtime_setoption()`. The function `mco_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 call `mco_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 calling `mco_runtime_getoption()`. (Please refer to the Reference Guide page `mco_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 functions

> > 2. `mcovtmem`: “virtual table” memory manager functions

> > 3. `mcotmursiw`, `mcotmvcc` or `mcotexcl`: Transaction Manager functions

> > 4. `mcomconv`, `mcomipc`, `mcompsx`, or `mcomw32`: memory devices functions

> > 5. synchronization library: functions that synchronize access to database objects as well as internal runtime structures (see below)

> > 6. `mcouwrt` or `mcowrt`: utility functions

> ### Persistent Databases

> Whereas In-Memory database applications use the “virtual tables” library `mcovtmem`, persistent database applications use library `mcovtdsk` and a file system library:

> - `mcofuni`: Unix-Linux file systems
> - `mcofw32`: Windows file systems

> Applications that use the eXtremeDB `mco_db_save()` or `mco_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 the `mcoseri` 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:

> - `mcoslnx`: for Unix-Linux
> - `mcosw32`: for Windows

> (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` and `eXtremeDB/target/bin.so`. The Direct Pointer version of the libraries is located in directories `eXtremeDB/target/bin.dptr` and `eXtremeDB/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 the `eXtremeDB/target/bin.dptr` or `eXtremeDB/target/bin.dptr.so` directories.