[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

C native layer (pre-announcement)

From: Dr. Torsten Rupp
Subject: C native layer (pre-announcement)
Date: Tue, 04 Mar 2003 10:20:51 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3a) Gecko/20021212

Dear developers,

I'm a software engineer at aicas GmbH, Karlsruhe/Germany in the group
"operating systems". As formerly discusses with Brian Jones and my
college Andy Walter I adapted our 'C native layer' for the GNU
classpath project to be able to port the library to different operating
systems. The first version of this new layer for GNU classpath under
Linux is now complete. Because of too much other things to do we had a
delay in providing the C native layer to the GNU classpath project
earlier, but now we believe we are ready.

Currently there is a discussion to merge some or all of the native
functions with the GCJ project. Because this will probably have some
influence to the changes I made to the GNU classpath sources I want to post the following read-me in this list before I check-in the new sources. Please feel free to send me your comments. We use the native layer already in our VM "Jamaica" and currently I'm working on native layers for other operating systems, like vxWorks, Cygwin or QNX.

Maybe someone who is familiar with the GCJ project, too, would also be
able to check if the C native layer could also be used with the GCJ
project and how to make some "super merge". Any hints are welcome.



The GNU classpath native layer

To enable GNU classpath to run on a diverse array of different hardware
platforms, a new native software layer has been added. This layer hide all
machine and hardware dependent issues except common available definitions,
which are ANSI C functions. For each targets system where the GNU classpath
library is to be used, a specific set of native layer functions have to be
provided. A generic set of functions is provided for Unix like systems
(currently tested only with Linux). For a new target system, some or
all native layer functions have to be rewritten. The following scheme
illustrate the native layer.

            Java API
     |    Java classes      |
     | -------------------- |
     |  C native functions  |
     | -------------------- |
  >> |    C native layer    |  <<
     | -------------------- |
     |   operating system   |
     | -------------------- |
     |       hardware       |

The C native layer is implemented as a set of C pre-processor native macros.
These macros expand to the appropriated native code. Macros are used
instead function calls to give optimal performance and small code size.
Of course in special cases, a macro can also expand to a function call
if this is needed. This approach provide a flexible and efficient
implementation of the native layer.

The naming pattern for native macros is like follows:

  TARGET_NATIVE_<module name>_<macro name>

where <module name> is a name of a module, e. g. FILE; <macro name> is
the name of the specific native macro, e. g. OPEN_READ.

The parameters for the macro use in general (with a few exceptions) the


where <parameter> is input/output parameter and <result> is the result
code TARGET_NATIVE_OK or TARGET_NATIVE_ERROR. Specific error codes
and error strings can be gotten with


(see also file target_generic.h).

For a single target system there exists two sets of native macros in
the files

  a) <target name>/target_native_<module name>.h
  b) generic/target_generic_<module name>.h

The macros in "a" are target specific implementations of native
functions, the macros in "b" are generic implementations (for Unix) of
the same native functions. If a native macro is not defined in the file
"a", then the definition in file "b" is used (there is a check to see if
a native macros is already defined elsewhere). This technique enables
"a" to 'overwrite' single generic native macros with specific native
macros for a specific target. In the default case, where only the
generic implementation of the native macros is used, the files in the
directory '<target name>' are empty except for the mandatory include of the
generic header file in the directory 'generic' at the end. Please
look at the existing Linux target specific files.

The directory and file structure is as follows.

    |--- target
    |      |
    |      |--- Linux
    |      |      |--- target_native_<module name>.h
    |      |      |--- ...
    |      |     ...
    |      |--- ...
    |      |--- generic
    |      |      |--- target_generic_<module name>.h
    |      |      |--- ...
   ...    ...    ...

Include hierarchy is as follows.

  native file <name>
    --> include 'target_native_<module name>.h'
                  <target specific definitions>
                  --> include 'target_generic_<module name>.h'
                                <generic definitions>

When writing native code, please take care with the following.

 - Use _only_ ANSI C specific functions directly which are available
   on all target systems with the same parameters, e. g. strdup() is
   not an ANSI C function, thus is is not available on all systems; mkdir()
   expect on some systems different parameters.

   !!!Do NOT use this functions in your native code!!!


   * if a function is not available, create a native macro in the file

     <target name>/target_native_<module name>.h

   * if it is a generic function, include a generic implementation in

     generic/target_generic_<module name>.h

   * Then use this macro in your native code.

- Avoid _all_ OS specific data types and constants, e. g. structures or error
   numbers. Instead, wrap them in a native macro and convert the values to
   basic scalar types like char, int, double or long.

 - Take care with 64 bit values; the are machine dependent. Not all
   target system support 64 bit operations. The macros in
   target_generic_math_int.h give a set of macros implementing 64 bit
   operations and constants.

 - Avoid - if possible - non-reentrant functions. Non-reentrant functions
   cause strange problems on some multitasking systems.

 - Avoid - if possible - dynamic data types created by malloc() and similar
   functions. Instead use (local) static variables to avoid stack usage.
   On some target systems, dynamic memory management is either slow or even
   dangerous. Moreover malloc()-calls can cause fragmentation of the system
   memory, which could result in a system crash or an application failure.

For some examples, please look in the current implementation for
Linux in the directory 'target/Linux' and the generic implementation in
the directory 'target/generic'.

                                        aicas GmbH, February 2003

reply via email to

[Prev in Thread] Current Thread [Next in Thread]