timezone weirdness
Hi,
I'm using the glibc version of jdk1.1.7v1a on a RH 5.2
system with glibc 2.0.7.
When trying to run some programs, I'm getting this message:
java.lang.Error: dtz null
at java.util.TimeZone.getDefault(TimeZone.java:94)
at
at
at ObjectSerialization.main(ObjectSerialization.java:8)
It also happens in the compiler:
java.lang.Error: dtz null
at java.util.TimeZone.getDefault(TimeZone.java:94)
at
at java.text.MessageFormat.format(MessageFormat.java)
at java.text.MessageFormat.format(MessageFormat.java)
at java.text.MessageFormat.format(MessageFormat.java)
at sun.tools.javac.Main.getText(Main.java)
at sun.tools.javac.BatchEnvironment.errorString(BatchEnvironment.java)
at sun.tools.javac.BatchEnvironment.error(BatchEnvironment.java)
at sun.tools.java.Environment.error(Environment.java)
at sun.tools.java.Environment.error(Environment.java)
at sun.tools.java.Environment.error(Environment.java)
at sun.tools.java.Environment.error(Environment.java)
at sun.tools.tree.Context.findOuterLink(Context.java)
at sun.tools.tree.Context.findOuterLink(Context.java)
at
sun.tools.tree.NewInstanceExpression.insertOuterLink(NewInstanceExpression.java)
at sun.tools.tree.NewInstanceExpression.checkValue(NewInstanceExpression.java)
at sun.tools.tree.Expression.checkInitializer(Expression.java)
at
sun.tools.tree.VarDeclarationStatement.checkDeclaration(VarDeclarationStatement.java)
at
sun.tools.tree.DeclarationStatement.checkBlockStatement(DeclarationStatement.java)
at sun.tools.tree.CompoundStatement.check(CompoundStatement.java)
at sun.tools.tree.Statement.checkMethod(Statement.java)
at sun.tools.javac.SourceField.check(SourceField.java)
at sun.tools.javac.SourceClass.checkFields(SourceClass.java)
at sun.tools.javac.SourceClass.checkInternal(SourceClass.java)
at sun.tools.javac.SourceClass.check(SourceClass.java)
at sun.tools.javac.Main.compile(Main.java)
at sun.tools.javac.Main.main(Main.java)
error: An error has occurred in the compiler; please file a bug report
(http://java.sun.com/cgi-bin/bugreport.cgi).
1 error
Here's the input with which it happens, save it as ObjectSerialization.java
The weird thing is that it happens only intermittently, though it's
reproducible for a given input.
I'm using green threads and no JIT, although it also happens with
native threads and TYA.
NB: the failure that happened when running the program was produced
after I compiled the .java file with Kaffe's pizza compiler.
More info, in case you're interested:
My env:
HOSTNAME=peerless.cs.utah.edu
LOGNAME=gback
PIXELFXDIR=/usr/pfx/Pixel2
MAIL=/var/spool/mail/gback
MACHTYPE=i386
WWW_HOME=http://www.cs.utah.edu/~gback/
TERM=xterm-color
HOSTTYPE=i386-linux
PATH=/usr/local/java/bin:/usr/bin:/sbin:/usr/sbin:/usr/local:/usr/etc:/opt/local/bin:/usr/local/bin:/usr/X11R6/bin:/opt/wordperfect/wpbin:/home/gback/bin:.:/usr/bin:/sbin:/usr/sbin:/usr/local:/usr/etc:/opt/local/bin:/usr/local/bin:/usr/X11R6/bin:/opt/wordperfect/wpbin:/home/gback/bin:.:/usr/bin:/sbin:/usr/sbin:/usr/local:/usr/etc:/opt/local/bin:/usr/local/bin:/usr/X11R6/bin:/opt/wordperfect/wpbin:/home/gback/bin:.:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/X11R6/bin:/opt/kde/bin:/usr/X11R6/bin
HOME=/home/gback
BITMAPDIR=/home/gback/bitmaps
SHELL=/bin/tcsh
USER=gback
VENDOR=intel
GROUP=cs-rsrch
DISPLAY=:0.0
HOST=peerless.cs.utah.edu
OSTYPE=linux
NNTPSERVER=news
OPENWINHOME=/usr/openwin
PWD=/home/gback/kaffe/test/fail
SHLVL=4
EDITOR=vi
CVSROOT=/usr/lsrc/flux/CVS
gback@peerless [79](~) > ls -l /etc/localtime
lrwxrwxrwx 1 root root 33 Apr 13 18:23 /etc/localtime ->
../usr/share/zoneinfo/US/Mountain
gback@peerless [80](~) > date
Tue May 4 16:16:08 MDT 1999
Any ideas? Is this a know problem?
Btw, is there a bug database for this jdk?
Thanks,
- Godmar
///
import java.io.*;
import java.util.*;
public class ObjectSerialization {
public static void main(String[] args) {
WR wr = new WR();
wr.write();
wr.read();
}
class WR {
FileOutputStream os = null;
ObjectOutput oo = null;
FileInputStream is = null;
ObjectInput oi = null;
WR() {};
// write an object
public void write() {
Dated = new Date();
try {
os = new FileOutputStream("SavedObject");
oo = new ObjectOutputStream(os);
} catch ( Exception e ) {
System.out.println(e);
System.out.println("WRITE: Unable to open stream as an object
stream");
e.printStackTrace();
}
try {
oo.writeObject("Today is: ");
Re: Call To Action on Java Lobby
> > I know that Kaffe is primarily a PersonalJava implementation, which is > why it breaks several progs. Is it being extended now? > Contrary to what was stated earlier on this list, Kaffe currently supports most 1.1 applications. It also runs on RH 6.0, btw, because you can simply recompile it for its version of glibc. It does not support applications relying on those parts of the 1.1 API that it does not implement yet. In particular, those relying on packages such as java.security. In some cases, you can use Sun's classes.zip in addition to Kaffe and still run the application. If your 1.1 or 1.2 application does not run, please consider submitting a bug report at www.kaffe.org. Kaffe is being extended to provide Java 1.2 functionality, however, at this point, only few classes are up to 1.2 standards. Basically, classes are extended on a need basis if people want to run 1.2 apps that rely on them. Hope that helps, - Godmar ps: I think that both Bernd & Michael are right. First, without having an vendor-neutral open source implementation, Java won't become an open standard. On the other hand, having such an implementation is not enough for it to become open. > On Sat, 8 May 1999, Bernd Kreimeier wrote: > > > Michael Emmel writes: > > > There has been a request on the Java Lobby www.javalobby.org > > > To reform the java lobby into a grass roots campaign to allow > > > Java developers to take a lager role in the determination of > > > java's future. > > > > IMO the time and energy is better spent in supporting clean > > room implementations like Japhar or Kaffe, Classpath, TYA, > > or gjc. > > > > > * J. Mark Brooks, Attorney at Law * > * P.O. Box 39, Randleman, NC 27317 * > * [EMAIL PROTECTED] * > * ICQ# 33436248* > * http://www.jmbrooks.net/law.html * > > > > -- > To UNSUBSCRIBE, email to [EMAIL PROTECTED] > with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED] > -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: two-tier threading for Java-linux?
I think Phill Edwards <[EMAIL PROTECTED]> plans to rewrite Linux's pthread package. You are right that the current state of linux- threads is unacceptable for a Java run-time, as is evident in the state of the 1.1.7native port. Implementing a hybrid architecture that would map multiple user-level threads on one or more kernel threads (as in Solaris) will still require kernel support, however. You guys need to convince Linus that that's necessary. He's looking at it only from the kernel perspective. I'm not sure what's actually needed. I'd guess you'd need at least a signal like SIGLWP, "all kernel threads are blocked", possibly another signal for cancel(?). You may be able to use some existing signals like linux-threads does, but I'd guess you run out at some point (doesn't Linux still have the only 32bit/signal mask restriction?) - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: How to measure efficiency?
>
> I've had similar problems measuring bandwidth. The greatest difficulty was the
> limited resoution of the available timers. It's a darn shame that a high
> resolution counter isn't available given all these fancy hardware. Milliseconds!
> Pah! You can do an awful lot in a millisecond. Ever since the Pentium was
> release there have been high resolution counters available - anyone written some
> code to access them ? - back then it was all restricted access only! Does Intel
> give a damn now ?
>
Here you go.
- Godmar
//
// CycleCounter.java
package kaffeos.sys;
/**
* Give Java programs access to the cycle counter on Pentium PCs.
*/
public class CycleCounter
{
/**
* read the current cycle counter
*/
public static native long read();
}
/*
CycleCounter.c
*/
/*
* Read the 64-bit timestamp counter (TSC) register.
* Works only on Pentium and higher processors,
* and in user mode only if the TSD bit in CR4 is not set.
*/
#if defined(i386)
#if HAVE_RDTSC
#define get_tsc() \
({ \
unsigned long low, high; \
asm volatile("rdtsc" : "=d" (high), "=a" (low)); \
((unsigned long long)high << 32) | low; \
})
#else
#define get_tsc() \
({ \
unsigned long low, high; \
asm volatile( \
".byte 0x0f; .byte 0x31" \
: "=d" (high), "=a" (low)); \
((unsigned long long)high << 32) | low; \
})
#endif
#else
#define get_tsc() 0
#endif
#include
jlong
Java_kaffeos_sys_CycleCounter_read(JNIEnv *env, jclass counterclass)
{
return (jlong)get_tsc();
}
~
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: How to measure efficiency?
On Linux, you'll probably also need a
static {
System.loadLibrary("nameofsofilethathascyclecounterdoto");
}
in CycleCounter.java.
- Godmar
>
> >
> > I've had similar problems measuring bandwidth. The greatest difficulty was the
> > limited resoution of the available timers. It's a darn shame that a high
> > resolution counter isn't available given all these fancy hardware. Milliseconds!
> > Pah! You can do an awful lot in a millisecond. Ever since the Pentium was
> > release there have been high resolution counters available - anyone written some
> > code to access them ? - back then it was all restricted access only! Does Intel
> > give a damn now ?
> >
>
> Here you go.
>
> - Godmar
>
> //
> // CycleCounter.java
> package kaffeos.sys;
>
> /**
> * Give Java programs access to the cycle counter on Pentium PCs.
> */
> public class CycleCounter
> {
> /**
> * read the current cycle counter
> */
> public static native long read();
> }
>
> /*
> CycleCounter.c
> */
> /*
> * Read the 64-bit timestamp counter (TSC) register.
> * Works only on Pentium and higher processors,
> * and in user mode only if the TSD bit in CR4 is not set.
> */
> #if defined(i386)
> #if HAVE_RDTSC
> #define get_tsc() \
> ({ \
> unsigned long low, high; \
> asm volatile("rdtsc" : "=d" (high), "=a" (low)); \
> ((unsigned long long)high << 32) | low; \
> })
> #else
> #define get_tsc() \
> ({ \
> unsigned long low, high; \
> asm volatile( \
> ".byte 0x0f; .byte 0x31" \
> : "=d" (high), "=a" (low)); \
> ((unsigned long long)high << 32) | low; \
> })
> #endif
> #else
> #define get_tsc() 0
> #endif
>
> #include
>
> jlong
> Java_kaffeos_sys_CycleCounter_read(JNIEnv *env, jclass counterclass)
> {
> return (jlong)get_tsc();
> }
> ~
>
>
> --
> To UNSUBSCRIBE, email to [EMAIL PROTECTED]
> with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
>
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: How to measure efficiency?
Chris, > > Do you have a makefile for this? > I made one and put everything here in case others are interested as well: http://www.cs.utah.edu/~gback/linux-jdk-cyclecounter> I even tested it and it runs. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Delivering Java Apps
I just like to address your reference to Kaffe being a personal java environment. After lurking a while on this list, I'm starting to realize that Kaffe's labeling as "PersonalJava" is an unfortunate one. PersonalJava (http://www.javasoft.com/products/personaljava/) http://www.javasoft.com/products/personaljava/spec-1-1-1/pjae-spec.html is a Sun product and specification for a subset of Java. This subset is roughly equivalent to Java 1.1.x, although some packages' API has been minimally changed and many packages, such as java.security or java.math, have been marked as "optional"---whatever that means. Kaffe (www.kaffe.org), on the other hand, strives to be a fully functional replacement for a Java 2 VM and its class libraries. However, it's not quite there yet. Realistically, it is mostly a Java 1.1 VM with support for some 1.2 classes, and it is lacking a few 1.1 packages (incidentally, it's missing java.security which PersonalJava marks as "optional" --- so I guess it makes some sense.) In some cases where Kaffe does not provide its own implementation, you can simply use another implementation. For instance, Kaffe does not provide a replacement for the servlet API JSDK2.x, but you can use Paul Siegman's or even Sun's package for that. Similarly, you can often use Sun's classes if they are written in 100% pure Java. Those parts of Sun's libraries that are not 100% pure Java --- namely those relying on classes in sun.* --- don't usually work if they require native methods. They sometimes don't even work if they do not require native methods, but use other backdoor interfaces. For instance, sun.io.CharToByteConverter is a classical example for an undocumented interface implemented outside the Java API. Sun does not give you a way to implement your own converters. To use Sun's classes with Kaffe, all that's needed is to copy a 1.1 classes.zip into the same directory that contains Kaffe's Klasses.jar, and Kaffe's driver will pick it up. If you try your application with Kaffe, and you find that it does not run to your satisfaction, you're encouraged to file a bug report with the bug database at www.kaffe.org. If it is a 1.1 app that does not use security, it should run. If it's a 1.2 app, we'd still like to know how it fails: this will give us an impression of which 1.2 packages people use to give them more priority. To address your question regarding memory requirements, Kaffe can run simple applets in its appletviewer with a 2 MB heap. This does not include the code of its VM and supporting native and other libraries (which are in separate shared libraries) For more details, see http://rufus.w3.org/tools/Kaffe/messages/5127.html http://rufus.w3.org/tools/Kaffe/messages/5130.html I hope that helps, - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Delivering Java Apps
> > In regards to setting minimum and maximum stack sizes, a "good value" is > really dependent on your application. If you're doing alot of file IO or > very intense computations, you might want to set those numbers fairly > high. The only way to really determine how much memory to explicitly > allocate to your application's VM is to experiment with different > settings. It seems to me that most folks usually use around 64 MB as the > max size. Your mileage may vary. > You are confusing "stack" and "heap". You do not use 64 MB as the maximum stack size. Secondly, file I/O and computation are the least important factors when it comes to choosing the right heap size for your application. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Redhat and Kaffe (was Re: First Step)
Nelson, Maksim, > > Nelson Minar wrote: > > > > What do people here think about Redhat having Kaffe installed by > > default as the binary "java"? I think it's a bad idea because Kaffe > > really doesn't support enough Java to be useful, at least to me. On > > the other hand, I want to support Kaffe and Japhar and other free > > software efforts, I don't want to exclude them. I've just seen a lot > > of people be confused by "why doesn't Java work on Redhat?". > > Considering that redhat probably isn't allowed to (or does't want to) > include the jdk in their distribution I think that Kaffe is the only > realistic solution to having java in Redhat. Also I hope redhat is > keeping up with kaffe's development as the latest release 1.0-beta4 is > quite better then previous ones, it even does a reasonable job on some > swing apps. > > > Does anyone know the story on the Klasses.jar they distribute as part > > of kaffe? What's the license terms, how is it different than classpath? > > I believe it's GPL, where as classpath is LGPL, though from memory there > is explicit permission for people to use it (link to the classlibs) for > non-GPL'ed programs. > This is correct. My impression is that the problems that people had getting Redhat's kaffe and the blackdown port to coexist occurred mostly in older versions (old meaning < RH 6.0 and < Kaffe 1.0b4). When I installed RH 6.0, it did not install kaffe---I had to download and install the kaffe 1.0b4 RPM separately. This was via ftp, however, maybe things are different for CDROM installers. Kaffe 1.0b4 should coexist with the blackdown JDK. By coexist, I mean that you can have a kaffe with a --prefix=A and the blackdown JDK in directory B with A!=B and things should just work --- you can control which java environment is being used either by setting your PATH properly or by using an explicit qualification such as /opt/kaffe/bin/java or /opt/jdk1_1_7vx_a/bin/java. You do not need to set any environment vars for kaffe to work (just like for the JDK). If that doesn't work for you, please consider complaining to [EMAIL PROTECTED] To my knowledge, the kaffe1.0b4 Redhat RPM is compiled with --prefix=/usr and will install itself in /usr/bin. Unfortunately, because of shared library pathname limitations, you can't simply move it: you'll have to recompile it with a different --prefix if you want it somewhere else. Kaffe 1.0b4 should complain if you attempt to use Sun's classes.zip with it before its own Klasses.jar (this is an error that had led in older versions to coredumps and the like). This can happen if people set a CLASSPATH variable to include classes.zip. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Class information in a static method
>
> > If you know the class' name, and I suspect that you do
> > since you are in a static method of the class, you can
> > do a Class.forName(className).
>
> Better still, className.class, and have it resolved at
> compile time rather than by a runtime lookup.
>
Miles, "className.class" is just a short-hand for this code:
{
...
if (_className == null) {
_className = getClassName("className");
}
...
}
private static Class _className;
private static getClassName(String cname) {
try {
return (Class.forName(cname));
} catch (ClassNotFoundException _) {
throw new NoClassDefFoundError(_.getMessage());
}
}
In other words, you're saving a try/catch clause at the expense of
one hidden static variable.
For example, this a.java
public class a {
Class x() {
return (a.class);
}
}
is compiled into:
public class a extends java.lang.Object {
static java.lang.Class class$a;
public a();
/* Stack=1, Locals=1, Args_size=1 */
static java.lang.Class class$(java.lang.String);
/* Stack=3, Locals=2, Args_size=1 */
java.lang.Class x();
/* Stack=2, Locals=1, Args_size=1 */
}
Method a()
0 aload_0
1 invokespecial #8
4 return
Method java.lang.Class class$(java.lang.String)
0 aload_0
1 invokestatic #12
4 areturn
5 astore_1
6 new #5
9 dup
10 aload_1
11 invokevirtual #13
14 invokespecial #9
17 athrow
Exception table:
from to target type
0 5 5
Method java.lang.Class x()
0 getstatic #11
3 ifnull 12
6 getstatic #11
9 goto 21
12 ldc #1
14 invokestatic #10
17 dup
18 putstatic #11
21 areturn
Hope that helps,
- Godmar
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Class information in a static method
>
> Godmar Back wrote,
> > Miles Sabin wrote,
> > > [snip: className.class vs Class.forName("className")]
> >
> > In other words, you're saving a try/catch clause at the
> > expense of one hidden static variable.
>
> Hmm ... well, a litte more than that. The lookup is done
> only once (to initialize the static).
Fair enough. An experienced programmer would probably include
such a guard as well.
>
> Still, I have to admit I was a bit surprised at the
> generated bytecode. I'd assumed that the constant pool
> would contain a reference to the class which would be resolved directly by
> the JVM at load time, rather by
> code at the first point of use.
>
> Is this just a compiler artefact (I've checked both
> jikes and javac from 1.2.2) or is there some intrinsic
> reason why it has to be done this way? I haven't been
> able to find anything obvious that bears on this in
> either the JLS or the JVM spec. I suppose it might allow
> some class loading to be deferred or eliminated ... is
> that the rationale?
>
One reason might be that there's no bytecode instruction in the
JVM's bytecode instruction set to load a java.lang.Class ref from the
constant pool.
- Godmar
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Benchmark results for Linux JVMs (formatted for 70 columns)
>
> Personally, I'd be interested to see info about non-Blackdown free
> JVMs. We don't hear too much about them on this list. That would
> have been an interesting comparison.
>
I ran the JVMSpec98 benchmarks from the cmdline to see how Kaffe
measures up against other JVMs.
Here's the estimates I got; they're all in seconds, lower is better:
compress jess db javac mpegaudio mtrt jack
ibmjdk 32.13 52.48 64.59 62.41 26.61 37.39 32.13
msjvm 33.90 51.40129.00 84.50 41.00 24.90 65.10
sun1.1.832.50 35.10108.00 117.00 30.30 58.40 42.20
jdk1.2 76.41 69.32158.47 111.12 60.66 62.10 83.15
Kaffe/jit3 47.54 104.33 98.49 111.99 91.44 115.31 142.26
tya15 123.08 90.00125.09 158.01 126.15 131.40 69.57
Kaffe/jit2 103.80 130.07132.95 171.29 175.49 159.69 265.76
These were run from the cmdline with a -mx64M setting, and not from
the spec harness. Consequently, I am unable to claim that these numbers
represent Spec numbers. Let's consider them rough estimates, please.
They're nothing more. The numbers above are the averages of running
the benchmarks 2-4 times (via -m2 -M4), without regard to outliers etc.
(though there weren't any.)
The JVMs involved were:
ibmjdk: IBM JDK 1.1.8 with native threads running under RH 6.0
jdk1.2: Blackdown 1.2 with sunwjit and green threads running under RH 5.2
Kaffe/jit2: Kaffe with the old jit (the one that's in 1.0b4) under RH 5.2
Kaffe/jit3: The current Kaffe which will be released as 1.0b5 shortly.
msjvm: Microsoft 1.1 JVM running under Windows 98.
sun1.1.8: Sun's 1.1.8 JVM running under Windows 98 (uses Symantec JIT)
tya15: Blackdown JDK 1.1.7a with newest TYA jit (1.5) under RH 5.2
Everything was run on identical hardware, a dual proc PII/350.
Note the obvious caveats: we have not only different versions of JVMs
involved, but even different OSes. ibmjdk's number are particularly
inaccurate because I didn't turn off the second CPU; I saw a CPU
utilization from 100%-112% for two benchmarks, javac and mtrt, which
by the way is impressive by itself and in javac's case most likely
indicates parallel asynchronous gc. But it puts ibm's javac number
somewhat in perspective.
In addition, while I'm confident about the memory settings for the
Linux versions, I'm unsure about the settings for Microsoft's JVM.
Note that these benchmarks all generate a tremendous amount of garbage
and a JVM's performance on these benchmarks is greatly influenced by
the amount of memory available as well as the performance of its
allocator/garbage collector.
Let me repeat it again: these are ballpark numbers; any detailed
conclusions you might want to draw are inadmissible.
I should maybe add a comment about the kaffe numbers. Tim Wilkinson
wrote and integrated a faster JIT ("jit3") during this summer. This
has led to a good speedup, allowing kaffe to surpass the 1.1.7/TYA 1.5
combo for all but two benchmarks. JIT3 is available for x86, mips, m68k,
and StrongARM, it's not available for sparc and alpha at this point.
Sparc is jit2, and alpha is interpreter-only currently.
It is also interesting to note how some benchmarks are dominated by a
single aspect of a JVM. jack, for instance, throws numerous exceptions.
A JVM's jack performance is strongly influenced by the speed with which
it dispatches exceptions. Switching Kaffe's exception mechanism
to use a hashtable instead of linear search to find exception handlers, for
instance, yielded a speedup from 238 seconds to the 142 seconds.
- Godmar
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Why is Linux thread locking so slow?
Hi,
Matt Welsh wrote:
>
>
> Hi folks,
>
> I have a simple Java program where 2 threads spin in a tight loop each
> grabbing the same lock and releasing it. This is on Linux x86 and has been
> tested using GCJ 2.95.1, Blackdown JDK 1.1.7v3 (native threads), and
> IBM JDK 1.1.8 (native threads). Note that I am on an SMP system (IBM
> Netfinity Dual PIII Xeon).
>
> When the lock is uncontended, performance is fine: about 2,000 loop
> iterations per millisecond. But with more than one thread trying to
> grab the lock, performance decreases considerably: down to 25 or 30
> iters/millisecond!
>
I believe that this problem may be caused by the lack of proper support
for user-level threading in the linux kernel.
Consider what linux-threads has to go through for a contended lock:
This code is from linux-threads 0.71:
int pthread_mutex_lock(pthread_mutex_t * mutex)
{
pthread_descr self;
while(1) {
acquire(&mutex->m_spinlock);
switch(mutex->m_kind) {
case PTHREAD_MUTEX_FAST_NP:
if (mutex->m_count == 0) {
mutex->m_count = 1;
release(&mutex->m_spinlock);
return 0;
}
self = thread_self();
break;
}
CONTENDED CASE
/* Suspend ourselves, then try again */
enqueue(&mutex->m_waiting, self);
release(&mutex->m_spinlock);
suspend(self); /* This is not a cancellation point */
}
}
acquire is implemented as (while !test_and_set() __sched_yield())),
which is usually uncontended and *not* the source of the slowdown.
Now, suspend is implemented like so:
static inline void suspend(pthread_descr self)
{
sigset_t mask;
sigprocmask(SIG_SETMASK, NULL, &mask); /* Get current signal mask */
sigdelset(&mask, PTHREAD_SIG_RESTART); /* Unblock the restart signal */
do {
self->p_signal = 0;
sigsuspend(&mask); /* Wait for signal */
} while (self->p_signal != PTHREAD_SIG_RESTART);
}
In other words, every contended case implies that the two processes
exchange user-level signals. (linux-threads uses SIGUSR1/SIGUSR2.)
What kind of performance can one expect with such a scheme?
On my dual PII/350 machine, I see ca. 600 iters/ms vs. 2000 iters/ms
as reported by Matt's program.
If I limit each thread to 50 measurements, I see the following
total runtimes as reported by time:
1 thread case:
2.470u 0.000s 0:02.47 100.0%0+0k 0+0io 99pf+0w
2 thread case:
5.780u 6.540s 0:07.99 154.1%0+0k 0+0io 99pf+0w
Note the 6.5 seconds spent in system code, plus
the additional 0.8 seconds or so spent in user mode (presumably in
signal handling related code)
One thing I'm wondering about is Linux's support for SYSV-style IPC
(semop etc.). Those appear to be kernel-supported semaphores. Maybe
the problem is not in the lack of kernel support, but could be fixed
by using SysV semaphores instead? It would definitely be worth a try.
On the other hand, aren't sysv semaphores optional when you configure
your kernel? As such, there may be reason to not hardcode reliance
on them in a glibc binary distribution(?) glibc could always
test for it at run-time, though.
I believe Xavier Leroy and/or the glibc people may be the right folks
to ask. I've cc'd Xavier on this mail, maybe he has some insights
as to what whether using semop would be an option.
I should mention that this problem is also affecting the native threads
version of kaffe, where we're also seeing slowdowns for highly contended
locks.
- Godmar
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Benchmark results for Linux JVMs (formatted for 70 columns)
> > >I ran the JVMSpec98 benchmarks from the cmdline to see how Kaffe > >measures up against other JVMs. > > Wow, nice numbers. I'm excited to see that ibmjdk on Linux is now in > the same ballpark (or faster!) as msjvm and the Sun VM on Windows. > Finally, I can hold my head up with pride :-) Why? Were you involved in developing the IBM JDK? ;-) Anyway, please note the following: numbers I did not give were the numbers of Sun's current 1.2 JDK on Windows. I expect those to be faster than their 1.1 numbers on Windows. I base this guess on the assumption that most of the run-time system that's not JIT-related in Sun's 1.2 code is the same code in both Windows and Linux. As I haven't seen Sun's code, I wouldn't know whether this is true. Secondly, I haven't seen the blackdown 1.2/TYA combo. From what I grasp it's not at the point yet where it would run spec98 (?) I expect that this will perform better than the 1.1.7/TYA 1.5 combo, and possibly better than the current kaffe. If not, TYA certainly has room to grow here given the jdk1.2/sunwjit numbers. To add another reason why nobody should draw conclusions quite yet: Kaffe's benchmarks were obtained with a version of its class libraries that was compiled with jikes, which is often considered to create the slowest bytecode among the different javac compilers. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Why is Linux thread locking so slow?
> > One thing I'm wondering about is Linux's support for SYSV-style IPC > (semop etc.). Those appear to be kernel-supported semaphores. Maybe > the problem is not in the lack of kernel support, but could be fixed > by using SysV semaphores instead? It would definitely be worth a try. > > On the other hand, aren't sysv semaphores optional when you configure > your kernel? As such, there may be reason to not hardcode reliance > on them in a glibc binary distribution(?) glibc could always > test for it at run-time, though. > > I believe Xavier Leroy and/or the glibc people may be the right folks > to ask. I've cc'd Xavier on this mail, maybe he has some insights > as to what whether using semop would be an option. > I admit it's a long time since I used SysV semaphores. Obviously, one of the reasons why they don't see widespread application is their lack of proper reclamation when a process exits (-> ipcs, ipcrm etc.), and the lack of a mechanism to create unique keys etc., etc. FWIW, I coded Matt's example using semaphores and I'm now seeing a degradation of about 60 iters/ms vs. 600 iters/ms for the contended case. Code is at http://www.cs.utah.edu/~gback/sem-test.c if anybody is interested. Note that I've simply replaced the pthread_mutex_(un)lock() with a call to semop(); this means that we're having a system call even in the uncontended case. This is not what a sem-converted linux-thread would look like. The 600->60 comparison only makes sense if one assumes that every single attempt to lock is contended. Nevertheless, my gut feeling is that even a linux-threads that would use Linux's SysV semaphores would perform as poorly as the current signal-based implementation. So, I believe that kernel support is indeed needed. A websearch turned up an old proposal by Ulrich Drepper from 1996, in which he proposes a /proc based mechanism to implement the POSIX.1b semaphores. See http://www.uwsg.indiana.edu/hypermail/linux/kernel/9611.2/0521.html He's also suggesting ways to get around the resource reclamation and namespace problems mentioned in my first paragraph. However, it appears as though his proposal was never implemented. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Why is Linux thread locking so slow?
Thanks for your answer, Xavier. Let me reply to some points below and ask some more questions. I hope this discussion remains interesting and relevant to the other subscribers on this list. > > > > I have a simple Java program where 2 threads spin in a tight loop each > > > grabbing the same lock and releasing it. This is on Linux x86 and has been > > > tested using GCJ 2.95.1, Blackdown JDK 1.1.7v3 (native threads), and > > > IBM JDK 1.1.8 (native threads). Note that I am on an SMP system (IBM > > > Netfinity Dual PIII Xeon). > > > > > > When the lock is uncontended, performance is fine: about 2,000 loop > > > iterations per millisecond. But with more than one thread trying to > > > grab the lock, performance decreases considerably: down to 25 or 30 > > > iters/millisecond! > > I'm not surprised. Given the 1-to-1 implementation model for > LinuxThread, each time a thread needs to suspend (e.g. because it's > waiting on a locked mutex), it needs to go through the kernel and > trigger a context switch. Context switch in the Linux kernel is > pretty efficient compared with other Unix kernels, but still on the > order of 20 to 40 microseconds. Clearly, in the uniprocessor case, linux-threads is handicapped by having to ask the kernel to switch between threads, because of the 1-to-1 implementation model. I fully agree with that. However, I think the case we're looking at here may be slightly different. In our case, one thread (A) is running on one CPU, and another thread (B) is running on another. Thread A holds a lock, thread B wants to acquire it. Once thread A unlocks the lock, thread B could just go ahead and run on the other CPU. In this case, *neither* CPU would have to context switch. It would simply be a system call executed on each CPU. Am I missing anything here? > > User-level threads or two-level threads fare better in these > circumstances, but are less efficient for doing I/O. Also, Linux > lacks the kernel support required for proper two-level scheduling. May I ask what you mean by two-level scheduling? Do you mean a hybrid threading scheme similar to Solaris, where some threads are scheduled as user-level threads at the process level, while the kernel only schedules fewer kernel-level threads (aka LWP), on top of which user-level threads are scheduled? Such a model would eliminate the caveat that every thread switch would incur a full kernel context switch. Or do you have something else in mind here? > > > I believe that this problem may be caused by the lack of proper support > > for user-level threading in the linux kernel. > > One thing I'm wondering about is Linux's support for SYSV-style IPC > > (semop etc.). Those appear to be kernel-supported semaphores. Maybe > > the problem is not in the lack of kernel support, but could be fixed > > by using SysV semaphores instead? It would definitely be worth a try. > > Using SysV semaphores as a suspend/resume mechanism for threads would > be no more efficient than the current signal-based implementation: > you'd still incur a kernel context switch for each suspend and resume > implementation. Let me point out though that your suspend operation right now incurs two system calls (sigprocmask and sigsuspend); this seems more expensive that a single semaphore_lock(), if it existed in usable form. Finally, I believe that a certain portion of the cost doesn't necessarily stem from the costs involved in the context switch; it stems from the fact that on top of the context switch you're going through the signal delivery path. This adds unnecessary overhead, especially in the case described above where the two threads run on different CPUs. Couldn't such overhead be avoid by having a dedicated lock/unlock system call? > > Using SysV semaphores as an alternative to mutexes is even worse: > you'd pay the cost of a system call on each mutex operation, not just > on those that contend for the mutex. Is this really true? Why would an implementation that uses test-and-set at user-level and that would fall back on the kernel lock/unlock construct not be applicable in this case as well as in the signal-based implementation? But as I've said, I completely agree with the other caveats of SysV5 IPC. I believe the reason I brought it up is to ask what we would gain by having kernel supported mutexes, if they could be provided in a usable form. > > The last thing I want to say is that regardless of the thread library, > high contention on mutexes will result in bad performance for your > application, especially on multiprocessors (because contention means > you're not taking advantage of all available parallelism). Thus, > properly written multi-threaded applications have very low mutex > contention, and consequently all thread libraries emphasize fast mutex > operations when there is no contention and don't worry too much about > performance in the other cases. You need to benchmark real > applications, not just
Re: Why is Linux thread locking so slow?
> > > >Clearly, in the uniprocessor case, linux-threads is handicapped by > >having to ask the kernel to switch between threads, because of the > >1-to-1 implementation model. I fully agree with that. > > > >However, I think the case we're looking at here may be slightly different. > >In our case, one thread (A) is running on one CPU, and another thread (B) > >is running on another. Thread A holds a lock, thread B wants to acquire it. > >Once thread A unlocks the lock, thread B could just go ahead and run > >on the other CPU. In this case, *neither* CPU would have to context > >switch. It would simply be a system call executed on each CPU. > > > >Am I missing anything here? > > What was the CPU (B) doing while waiting for the lock to be released by > CPU (A)? Normally it would not be just sitting there spinning on trying > to get the lock but rather it would be putting that thread (process) to > sleep waiting for a signal - that process is at least as much as a > context switch to get out of since that is exactly what it would do - > context switch back to the thread (process) that is asleep when the > signal comes in. I looked at the halt and scheduling code in my 2.2.12 kernel source. Maybe we need some people with more microarchitectural knowledge here. The main costs of a context switch come from the fact that the TLB must be invalidated. On architectures with a software tlb, explicit instructions must be issued to that effect. On the x86, I don't know when it will happen. Does executing a "hlt" instruction cause it? I don't believe so? Does simply reloading segment registers with new global descriptors cause this? Probably. Does resuming a CPU that has gone into a "hlt" instruction cause the segment registers to be reloaded, even if the same process is to be resumed on that CPU? That is the question IMO. I believe that if CPU (B) goes idle while waiting for CPU(A) to resume it, and after it resumes it will run the same process it ran before the hlt, it should *not* incur the same cost as if it switched contexts and resumed a different process. At least that's what I conclude from looking at kernel/sched.c. The scheduler there attempts to reschedule a process on the CPU on which it last ran. Why does it do that? Do I misinterpret that code? Are there other reasons? I should mention another source of overhead here: to resume a process on a different processor, interprocessor interrupts have to be used. How fast/slow are those on the x86? > > If you design a specific system that runs only two threads on two processors > then you can easily make this a special case. However, in the general > case of an OS like Linux (especially if other programs are also running > on the same system) there is a strong reason not to just loop on a lock > until you get it (unless they are micro-locks where the duration of the > lock being held is significantly less than the overhead of waking up > someone else - and even then one must look at the number of times this > happens and the number of contenders) This is true, but as you stated in your previous paragraph it's not the case here. The locks we're looking at are not implemented as direct spinlocks. > > [...] > >> Using SysV semaphores as an alternative to mutexes is even worse: > >> you'd pay the cost of a system call on each mutex operation, not just > >> on those that contend for the mutex. > > > >Is this really true? > >Why would an implementation that uses test-and-set at user-level > >and that would fall back on the kernel lock/unlock construct not be > >applicable in this case as well as in the signal-based implementation? > > Be careful here - there are other things that may be at work in a > multi-processor system and thus a system call may always need to be > involved. The overhead of such a call can be minimized in the > non-contended case but only to a certain point. > This is true. I asked some colleagues here at Utah, and indeed there's systems that always involve a system call. Some systems, though, such as HP-UX, can sometimes avoid system calls by sharing some data structures between userland and kernel. However, such an approach has different trade-offs, as you say. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Why is Linux thread locking so slow?
> > > > So, I believe that kernel support is indeed needed. > > Don't do in the kernel what can adequately be performed in user space. > Let me add my own data here... I modified Matt's program to get better > timings, and compared mutexes to a spinlock implementation for ix86: > [...] > For such short lock durations system calls are not effective. During > the time one thread spends in sched_yield(), perhaps several > microseconds, another thread may grab the spinlock hundreds of times > succesfully. The effect is to inflate overall throughput but severely > increase latency and diminish concurrency. > > On the other hand, for a uniprocessor spinlocks are not effective. > [...lots of benchmark results delete, please refer to Jeff's mail] > My main point is that it is not adequate to measure simple lock > throughput (iters/msec) to judge the quality of a lock algorithm, nor is > one algorithm best suited for all situations. The spinlock code is > convenient because it is easy to tune for different machines, especially > SMP kernels. The lock-test porgram is not very realistic since most CPU > time is spent competing for a lock, but it serves as a reasonable > benchmark for lock contention. > Jeff, I'm not sure I understand what you're trying to say here. Your measurements demonstrate that spinlocks are faster than anything else if there's at least as many processors as there are threads. I fully agree and expect this. But I don't see what I should conclude? That I should use spinlocks implemented via atomic exchange operations in cases like the one we discussed, where you have one heavily contended lock in your application? If that were your conclusion, I would have to disagree, simply because we cannot assume that there's at least as many processors as there are threads. We're not looking for a decision as to whether to use spinlocks or not, we're looking for a way to improve the implementation of pthread_mutex_lock in the contended case. We cannot even assume that the lock is only held for short-durations, which is another prerequisite to using spinlocks to my knowledge. But maybe really don't understand what you are suggesting. Could you explain? - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Linux JVMs
> > You mentioned in a previous email the ibmjdk, is that Jikes? If not what is > Jikes as I thought that was the IBM JVM. Do you happen to know what Java > version Jikes is comparable to? > No, IBM's JVM is IBM's port of Sun's JVM. It's a JVM. jikes is a java source to java bytecode compiler written in C++. The only thing they have in common is that they're both from IBM. Both can be obtained from IBM's alphaworks website. (*) - Godmar Use google.com, type "jikes alphaworks download", hit the "I feel lucky" button and I bet you'll be almost there. -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Why is Linux thread locking so slow?
>
> My earlier question stands: why does boehm-gc use spinlocks and not
> pthread mutexes, or condition variables? Was it a deliberate decision, or
> ignorance on the part of the Linux porters? That choice suprised me a
> little, since garbage collection can run for long durations and cause
> extensive spinning on waiting processors.
The version of boehm I downloaded a while ago says this:
/* Reasonably fast spin locks. Basically the same implementation */
/* as STL alloc.h. This isn't really the right way to do this. */
/* but until the POSIX scheduling mess gets straightened out ... */
Secondly, tries to find out whether it's on an uni or smp
by spinning a number of times and then adjusting accordingly.
If it does suspect that it's being scheduled against the other
process on the same processor, it backs off and uses nanosleep
to give up the CPU.
They're careful to make sure that nanosleep doesn't spin:
/* nanosleep(<= 2ms) just spins under Linux. We*/
/* want to be careful to avoid that behavior. */
Furthermore, note that this lock protects both allocation and collection.
Allocation is non-blocking and quick.
If a collection happens ("GC_collecting" is set) the code jumps right
to the "yield:" label where it does not spin. So the long durations of
gc is not an issue. (At least in the version I'm looking at - 4.13alpha3)
> For that matter, Linux pthreads is optimized for uniprocessors. It could
> be improved by reading /proc/cpuinfo on startup to determine if it is
> running on a SMP kernel. I hacked libpthread.so once for MP use, and
> observed up to a 30% speedup on some of my real-world Java code.
It would be nice to see these hacks.
What exactly did you change to optimize for MP use?
>
> What exactly do you wish to improve in pthread_mutex_lock? There are so
> many variables, such as average latency with or without lock contention,
> lock concurrency, resource utilization, predictability (ratio between
> average and worst case), etc. Clearly the technique you favor depends on
> whether you are designing for maximum throughput, real-time, or other
> needs.
>
>From what I can see, pthreads already does a good job for latency
in the uncontended case. I'd like to see the latency contended case improved.
I don't care about lock concurrency or any measure of fairness (for now).
I'm not sure what you mean by resource utilization (do you mean CPU resource
utilization, i.e., not wasting cycles due to spinning?) I think I'd care
about that too.
Basically, all I want is to not have applications with multiple threads and
highly contended locks (java runtime systems) run slower on two processors
than on one processor. If they don't run twice as fast, I can live with that.
- Godmar
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Why is Linux thread locking so slow?
Thanks for your all your answers. I think we got an insightful discussion going. I also think we got almost everything cleared up. Let's hope that some mainstream magazine publishes numbers that show just how Linux is being outperformed at the pthreads level and that that changes the attitudes of the linux kernel team. (Which is what happened with some Apache benchmarks, from what I can tell.) Well, you'll still need to have a convincing implementation... I'm still feeling a bit misunderstood on one point, though: > > > However, I think the case we're looking at here may be slightly different. > > In our case, one thread (A) is running on one CPU, and another thread (B) > > is running on another. Thread A holds a lock, thread B wants to acquire it. > > Once thread A unlocks the lock, thread B could just go ahead and run > > on the other CPU. In this case, *neither* CPU would have to context > > switch. It would simply be a system call executed on each CPU. > > Assuming B doesn't do busy-waiting, if it finds the mutex locked by A, > it has no choice but to suspend and presumably the kernel will then > switch context to another runnable process. Later, A unlocks the > mutex, and seeing that B is waiting on it, will restart B. > You say that the kernel will then "switch context to another runnable process". My argument was considering the case that there is *no other runnable* process in the system (i.e., 2 processors, 2 runnable threads)-- and that the second CPU will therefore go idle until it is resumed by the first CPU via IPI. My question was whether *this* case is still as expensive as a context switch. Secondly, Jeff had commented that the Netscape NPSR people did implement some kind of two-level scheduling. I had always thought that this would require kernel support. For instance, on Solaris, the kernel uses SIGLWP to inform the user-level scheduler when it has run out of LWPs and needs to create new ones. If you don't have SIGLWP, you can't use native I/O (i.e., read(2) etc. on blocking filedescriptors)---how does netscape do it? - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: [ANNOUNCE] LaTTe Java Virtual Machine
>
> I said this on comp.compilers and think it may interest some in this
> news group. According to the site, the performance of this VM is
> comparable to Sun's hotspot. It's released under a BSDish license.
> Anyone with more Java VM programming experience cares to take a look at
> it and see how hard would it be to port it to Linux?
>
>From what I can tell, it should be easy to port Linux---Sparc/Linux,
that is.
They basically started with the last BSDed kaffe (0.9.2) and completely
rewrote the engines and the allocator/gc subsystem. In doing so, they
sacrificed kaffe's portability layer in order to speed up execution on
the sparc platform.
(The top of the mark stack in the gc, for instance, is declared as
void * mark_top asm("g5"); or something similar --- hey, what the heck)
They also optimized their memory allocator for a uniprocessor
platform by locking out other threads during allocations---this saves
a gc_lock and the contention is can cause and doesn't require them
to provide per-thread allocation arenas. Not suitable for SMP, but
fair enough.
They also don't implement stack limit checking because of the associated
performance costs, which in my view may make some of their results
look not as good. But I haven't read their discussion in their paper
yet.
Latte at this point may be more suited as a research platform (which
is what it's intended for) than as a usable JVM, given that only a
subset of 1.1 is implemented.
The codebase is *very* readable and *very well* documented, and easy to
understand---especially for someone with a kaffe background.
- Godmar
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Benchmark results for Linux JVMs (formatted for 70 columns)
> > >>To add another reason why nobody should draw conclusions quite yet: > >>Kaffe's benchmarks were obtained with a version of its class libraries > >>that was compiled with jikes, which is often considered to create > >>the slowest bytecode among the different javac compilers. > > > >Is it? Can you point me towards some info about this issue with Jikes. > >I'd like to read more about it. > My statement was based on examining the jikes bytecode while fixing some of the problems it caused for kaffe. I saw lots of nops and aload/aload pairs where a aload/dup would have been better, and lots of gotos jumping to the next instruction etc.Basically the kind of stuff that simple bytecode optimizers would fix. Before anybody draws conclusions: this was with jikes 0.x (forgot which) and time has passed since. Secondly, the whole thing is dubious anyway since these differences disappear for most jit compilers anyway, as Matt pointed out. Only interpreters and such jits that perform peephole translation (such as kaffe) might be affected by this to a certain extent. Also, I'd like to add that I've observed in more than one occasion that jikes was the only javac compiler who'd produce the correct bytecode for certain constructs (for example interface dispatch, constructors of inner classes) I've also seen warnings coming from jikes where it would say something to the effect: "It is unclear whether we should allow what you coded... awaiting clarification of JLS". I thought that was rather cute. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: Sun and Inprise Java 2 announcement
> > I think it is the drawback of the "Open Source" model. Technically, > you can take any code and release it as yours after few changes. > Technically, this has nothing to do with the "Open Source" model. Sun's JDK, the community license, or the blackdown port have little in common with open source efforts, precisely because you can't just take any code and release it after few changes. See the definition at www.opensource.org/osd.html. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Kaffe (was Re: Sun/Inprise/GPL Linux JDK)
Since Kaffe came up on this list, let me add a few comments about it: > > Kaffe is a clean room implementation to the spec but they have expanded the > language in some interesting ways. I seem to recall they used the MS alternative > to JNI but maybe they put in JNI as well. Kaffe fully supports JNI. In fact, the native parts of its AWT are completely written in JNI. In addition to JNI, it also supports the faster KNI (kaffe native interface) which is similar to Sun's first pre-JNI native interface (which in a way is similar to Cygnus CNI w/o vtables). Technically, there's no need to use JNI for kaffe's libraries itself; due to the lack of an incremental or generational collector this is currently a complete loss in every respect. You're paying a performance penalty for JNI that is usually offset by enabling more precise gc. Nevertheless, third-party JNI libraries are fully supported to the extent that JNI is specified. Keep in mind that the JNI environment as an execution environment is highly underspecified. Support for MS's JDirect stuff is available too, but it's an extension only, not necessary for the base system and I don't think anybody uses it. Quite frankly, I think it was just a funding and good-or-bad PR vehicle for Transvirtual. (Transvirtual plays the same role for Kaffe that Cygnus plays for libgcj and other sourceware projects.) Unlike the blackdown patches, though, the MS extensions are GPLed, I should add; but from a technical point of view, I haven't even looked at them at this point. > From a recent read of Kaffe I got the > impression that they stopped at 1.1.1 and did not know if they were headed for 1.2 > or 1.3. > No decision as to stop at 1.1.1 has been made. For more information and to learn how you can contribute, see www.kaffe.org What gets implemented, gets implemented. Unlike Blackdown, kaffe is an open source project, so most people are welcome to contribute to a codebase that is out of Sun's control. Because of the cleanroom nature, people who have signed license agreements to obtain Sun's source cannot. I think it is impressive what Kaffe has accomplished so far. Despite only 2 people working full-time on it, and a handful of part-time contributors, it's really a usable 1.1 environment. It's not as fast as IBM's or MS's JVM (by far not), but it easily surpasses for instance the 1.1.7 Blackdown with the latest TYA. In addition, it's reasonably modular so people can port it to new architectures and new threading systems etc. easily. What is lacking is thorough testing. In open source projects, this is usually done with the support of the community. While Kaffe has picked up here, it still doesn't have the support projects like Apache or the Linux kernel have. For this reason, it's currently only developed by Transvirtual (who are the owners and also sell a related version) and by a few people who use kaffe for academic projects, to prototype systems. (Plus maybe a dozen regular (small) contributors on the mailing list.) I think one reason for this is that we didn't invent Java --- it was invented by Gosling and others at Sun. We shouldn't forget that---we're only reimplementing it in trying to create a multi-platform programming environment for a reasonably modern language. In addition, while the blackdown ports haven't been flawless, they provide a no-cost alternative for Linux. Unlike what RMS wants you to believe, few people actually care about licensing as long as there is some software they can use for free. Another reason, I think, is that a lot of people test their complex applications, and they'll stop as soon as they hit the first unimplemented or not compatibly implemented method. Even if you have 95% coverage, you won't be able to run your software if parts are missing. This creates the perception that kaffe can't run more complex apps. If someone takes the time, though, it's possible to fix kaffe to run such rather complex apps as netbeans, jigsaw, the icebrowser beans or the citrix ica client. (All of which are examples of apps Tim Wilkinson has successfully debugged) Plus, of course, there's the many cases where the JDK spec is missing or lacking and stuff has to be black box revenged. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Re: C# -- the Java killer?
> > * Virtual methods are supported but you have to use the 'virtual' and > 'override' keywords - a bit ugly. Otherwise methods are treated as > non-virtual. My guess is that they are trying to avoid the problem > that Java has with nearly everything being a virtual method, and the > resulting performance issues. However, a static C# compiler should be > able to devirtualize everything since there's no dynamic class loading. > Actually, this choice is something I very much agree with. I think that Java got it wrong when it made "virtual" the default. The performance issues you mention are the least of my concerns. The primary problem is that virtual methods are error-prone. They can easily break base classes if a subclass that overrides a method does not implement the contract of the overridden method 100%, which frequently happens. Especially in closed-source (or bytecode only) base systems where you extend classes in the "programming by difference" paradigm such mistakes are hard to impossible to track down. Granted, having to declare a function "virtual" does not guard against such mistakes. But at least it puts up a warning sign that tells the implementor to be especially careful when defining that method's semantics, and it tells the caller to not rely on hidden knowledge about their implementation. In essence, it's an issue of deciding what's the normal, common case, which requires less attention, and what is the less common case which, because of its semantic implications, needs conscientious attention when used. - Godmar -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
