Creating user-defined C functions (D3 UNIX)

A user-defined C function can be incorporated in the D3 monitor, thus making C functions available to all applications running on the system.

This way of customizing the monitor should be reserved to functions that are widely used in the applications running on the system (such as a math package, graphics, communications, and so on). It is a relatively complex procedure that should be attempted only by programmers experienced both in D3 and UNIX.

The main advantage of this procedure is efficiency. The cost, however, is the loss of portability to non-D3 UNIX platforms. Also, the user-defined built-in function must be integrated in the monitor at every new release.

Integrating a C function in the monitor requires:

  • Building a table to inform the FlashBASIC compiler about the new user written function.

  • Building a branch table for use by the monitor to access the user written function.

  • Creating a new monitor.

A description of the necessary procedures is shown in the example below. The tools used in this section are described completely under their respective entries in the documentation.

Warning: It must be emphasized that, especially while debugging with UNIX debuggers, changing data in the D3 environment can cause damage to the database.

Most of the procedures below can be done from TCL (by prefixing UNIX commands with an !). The D3 process has to be stopped (disconnected), however, when the new monitor is about to be created, because most UNIX versions do not allow rebuilding an object module that is currently being executed.

Complete the instructions below to add a new function to the monitor:

  1. Logon to the dm account.

  2. Add the new module to the FlashBASIC-C interface. Type:

    addbi fpadd fpsub fpmul fpdiv
    

    The TCL addbi command adds the functions to the item dm,messages, user.builtin and creates and compiles the file px_user.c which is the built-in user branch table.

    This step needs to be done only once.

  3. Edit and compile the C program. After entering the C program, compile it. Type:

    !cc -c fp.c
    

    This creates the module fp.o.

  4. Add the new module and the User branch table to the user function library. Type:

    !ar vru libgmu.a fp.o px_user.o
    
  5. Disconnect the current D3 Process.

    If the current line is line 0, the D3 virtual machine shuts down. At this stage, because user processes normally execute the reference monitor /usr/bin/d3, it is not necessary to stop the virtual machine.

  6. Return to the shell. Type:

    disc
    
  7. Build the new monitor. Type:

    make -f /usr/lib/pick/Makefile
    

    This creates a monitor named d3 on the current directory. If errors occur during its creation, it may be necessary to make modifications to the Makefile.

  8. Test the new monitor

    Generally, it is not necessary to shutdown the D3 virtual machine to start a user process on a new monitor. The new monitor can be executed by one or more user processes for test purpose.

  9. Type:

    ./d3
    

    This starts a user process executing the new monitor. To make any changes, repeat the procedure from steps 3 to 8 until the C function is working properly. Debugging can be done with the usual UNIX debuggers like sdb or dbx.

  10. Logon to dm. Enter this FlashBASIC program:

    bp fpdiv:
    cfunction unix.builtin, user.builtin
    * Reserve space for the resulting string
    char result[64]
    * Call the C function (no return code)
    %fpdiv("1.23e-9", "1.2e-3", result, 64)
    * Extract result (0 terminated string)
    print 'Res=':field(result,char(0),1)
    
  11. Compile and run it:

    compile bp fpdiv
    run bp fpdiv
    Res=1.02500000000000013890527183341e-06
    
  12. Repeat steps 3 to 8 until the new function works properly.

  13. Move the monitor to the working directory.

    When the new monitor is properly tested, it can be moved to the common directory, where Users can access it. Copying the new monitor must be done as super-user (root) because the directory is write protected.

    su (enter password)
    chmod 06755 d3
    chown root:bin d3
    cp d3 /usr/bin
    
  14. Shutdown and reboot the D3 virtual machine.

    User processes now execute the new monitor.

Example(s)

Consider the C functions below that perform the four basic operations on two strings, s1 and s2, representing floating point numbers in FORTRAN F-format or E-format ("[-]d.dddE[+-]dd"). A string, up to p characters long, representing the result, is returned into s3.

fp.c :
double atof();
fpadd(s1, s2, s3, p)
char *s1, *s2, *s3;
int p;
{
   gcvt(atof(s1)+atof(s2), p, s3);
}
fpsub(s1, s2, s3, p)
char *s1, *s2, *s3;
int p;
{
   gcvt(atof(s1)-atof(s2), p, s3);
}
fpmul(s1, s2, s3, p)
char *s1, *s2, *s3;
int p;
{
   gcvt(atof(s1)*atof(s2), p, s3);
}
fpdiv(s1, s2, s3, p)
char *s1, *s2, *s3;
int p;
{
   gcvt(atof(s1)/atof(s2), p, s3);
}