Contents | Prev | Next |
J2ME CDC 1.0
Porting Guide |
The CDC differs from the PersonalJava platform in the following areas:
- makefile structure
- Host Programming Interface, or HPI (VM porting layer)
See HPI Differences.
- Java 2 SDK v1.3-based
Classes and native methods should not require much change from the reference implementation. See Porting the Platform-Dependent Class Library Support.
- Debugger support
The debugger support requires some porting of the networking and dynamic linking code.
Converting an existing port of the PersonalJava platform to a CDC port will require the most effort in the makefile and HPI areas.
The most significant HPI differences are in the following areas:
- JNI native method invocation
- Threads
- Monitors
JNI Native Method Invocation
The CVMjniInvokeNative() function replaces the sysInvokeNative() function from the PersonalJava platform. This function translates the Java language calling convention into the C convention used in native methods. The CVM passes all the arguments in the Java stack, and expects the results to be placed there as well.The CVMjniInvokeNative() function differs from the sysInvokeNative() function in the following ways:
- CVMjniInvokeNative() uses terse signatures that take up less space and allow faster parsing.
Because the signature codes were ASCII characters, the sysInvokeNative() reference implementation had to perform multiple compares to find a match. For CVMjniInvokeNative(), the signature code is a 4-bit integer, allowing a fast table lookup or computed branch or jump.
- The return value is stored into a structure, a pointer to which is passed as an argument.
For sysInvokeNative(), the return value was stored onto the Java stack.
- CVMjniInvokeNative() returns the number of words taken up by the result value, or -1 if the result is an object.
sysInvokeNative() returned the new top-of-stack pointer.
Threads
Because CVM does more work above the porting layer than the PersonalJava VM did, the porting layer has been simplified significantly.
The following table compares CVM thread functions to PersonalJava thread functions. It does not include the full method signatures and descriptions. For full signatures and descriptions of the CVM thread functions, see the threads.h section of the HPI reference chapter.
CVM Function Comparison to PersonalJava VM Functions CVMthreadAttach() Replaces sysThreadAlloc() and the parts of sysThreadCreate() that fill in the sys_thread_t pointer. Associates a CVMthreadID pointer with the current thread. CVMthreadAttach() is called for threads created by CVMthreadCreate() as well as for existing threads that are attached using the JNI AttachCurrentThread() function.
CVMthreadCreate() CVMthreadCreate() is simpler than sysThreadCreate(), because CVM does more work above the porting layer than the PersonalJava VM did. A CVMThreadID is allocated by the CVM and associated with the thread using CVMthreadAttach(). There is no need to allocate and return a thread-private structure (sys_thread_t), and there are no flags and no thread cookie. The CVM maintains the list of threads, so the HPI doesn't have to do it. (There is no equivalent to sysThreadEnumerate().) The thread is not started in the suspended state. CVMthreadDetach() Replaces sysThreadFree() and sysThreadExit(). Disassociates the CVMthreadID pointer from the current thread. CVMthreadDetach() is called for threads that have been detached using the JNI DetachCurrentThread() function, as well as for threads created by CVMthreadCreate(), when the start function is ready to return.
Unlike the PersonalJava threads implementation, CVMthreadDetach() does not need to zero out Thread fields such as eetop and PrivateInfo. Nor does it need to make any calls into the VM to perform further cleanup, as was needed for monitors in the PersonalJava implementation.
CVMthreadDetach() only needs to deallocate any resources that were allocated by CVMthreadAttach(). The CDC reference implementation uses the POSIXthreadDetach() function, which simply makes sure that future calls to CVMthreadGetSelf() return NULL.
CVMthreadInterruptWait() Equivalent to sysThreadInterrupt() in the PersonalJava platform. CVMthreadIsInterrupted() Equivalent to sysThreadIsInterrupted() in the PersonalJava platform. CVMthreadResume() Equivalent to sysThreadResume() in the PersonalJava platform. CVMthreadSelf() Equivalent to sysThreadSelf() in the PersonalJava platform. If a CVMThreadID pointer is associated with the current thread, then CVMthreadSelf() returns the pointer. Otherwise, it returns NULL. CVMthreadSetPriority() Equivalent to sysThreadSetPriority() in the PersonalJava platform. CVMthreadStackCheck() Equivalent to sysThreadCheckStack() in the PersonalJava platform. CVMthreadSuspend() Equivalent to sysThreadSuspend() in the PersonalJava platform. CVMthreadYield() Equivalent to sysThreadYield() in the PersonalJava platform. Monitors
For the PersonalJava platform, the VM porting layer had to implement a monitor abstraction. For the CDC, the monitor implementation has moved into the CVM, and the VM porting layer instead needs to implement mutex and condition variable abstractions.
The CDC reference implementation uses POSIX thread functions. The mutex and condition variables implementation is in src/porting/posix/posix_sync_md.c. If your platform provides the POSIX threads library, you may be able to use this file with no changes.
If you ported the PersonalJava VM and based the monitor implementation on a private mutex and condition variable layer, as is the case for the PersonalJava reference implementations that used Solaris native threads, you can reuse your implementation with simple changes. Examples of these simple changes are shown in the following table. The sys_mon_t structure from the PersonalJava platform is replaced by the combination of the CVMMutex and CVMCondVar structures in the CDC.
CDC Functions Corresponding Personal Java VM Functions CVMBool CVMmutexInit(CVMMutex* m);
void CVMmutexDestroy(CVMMutex* m);
CVMBool CVMcondvarInit(CVMCondVar *c, CVMMutex* m);
void CVMcondvarDestroy(CVMCondVar *c);int sysMonitorInit(sys_mon_t *mid);
int sysMonitorDestroy(sys_mon_t *mid);void CVMmutexLock(CVMMutex* m);
void CVMmutexUnlock(CVMMutex* m);int sysMonitorEnter(sys_mon_t *mid);
bool_t sysMonitorEntered(sys_mon_t *mid);
int sysMonitorExit(sys_mon_t *mid);void CVMcondvarNotify(CVMCondVar* c);
void CVMcondvarNotifyAll(CVMCondVar* c);
CVMBool CVMcondvarWait(CVMCondVar* c, CVMMutex* m,
CVMJavaLong millis);int sysMonitorNotify(sys_mon_t *mid);
int sysMonitorNotifyAll(sys_mon_t *mid);
int sysMonitorWait(sys_mon_t *mid, int millis, bool_t clear);Additional notes on monitors are organized by topic below:
- Mutex locking
In the CDC, a thread never attempts to lock the same mutex more than once. This differs from the behavior of sysMonitorEnter and sysMonitorExit in the PersonalJava platform, which required a recursive entry count.
- Monitor waiting
You can modify your sysMonitorWait implementation so that the "clear" flag is always true (the interrupted state should always be cleared). A recursive entry count is not needed, nor is a check of the monitor ownership (or in this case, the condition variable mutex).
- Monitor notification
You can modify your sysMonitorNotify and sysMonitorNotifyAll implementation so that it no longer checks that the current thread owns the monitor. This check is unnecessary in the CDC.
For a description of the definitions required to support mutexes and condition variables for the CVM, see the sync.h section of the HPI reference chapter.
Copyright © 2000
Sun Microsystems, Inc.
All Rights Reserved.
Please send comments to: jcp-cdc-comments@eng.sun.com |
![]() |