tisdag 9 maj 2017

Signs of life, or something

Sounds like silence

The silence on the blog should not be taken as sign of abandonment. Work has been simmering slowly the last few months, however my actual paid work, and other stuff have taken most of my time.
The activity on the blog should not be taken as a sign of great achievements, however. I've been working on OpenJDK 8 lately, and before getting to a point of actually having something to run and test, there's quite a few things that need to be in place. I'm using IcedTea 8, an official OpenJDK project which, and I quote, "aims to make it easier for users to build and deploy OpenJDK". It's basically a set of files which uses the official OpenJDK code base, but sligthly alters it, and adjusts the build process, so it's possible to, for instance, use JamVM instead of HotSpot, do cross compiles, and tweak the JDK in other ways.

Now I've gotten to the point where all autoconf, makefiles, et.c., can generate a cross compiling environment for PPC 32 bit AmigaOS, and I can just do make, and find what's missing as I go along. The stuff missing is Amiga-specific Java classes for AmigaOS stuff, for instance the Java class java/io/AmigaFileSystem.java, which then also needs some native stuff in java/io/AmigaFileSystem_md.c that connects down to real AmigaOS code. When finding something missing, I usually glance at the Windows or Solaris OpenJDK code, try to understand what it does, copy either implementation, and alter it to fit AmigaOS. Sometimes I can also re-use old GNU Classpath code and tweak it to fit the OpenJDK world. All in all, I'm kind of the Amiga-Java Dr. Frankenstein, trying to bring what pieces I have together. Now, I should also say that its not all copy-and-paste, I do actually write some of my own code. You can't find this on stackoverflow, ya know!


It compiles!

I mentioned cross-compile above, meaning that I'm on my Linux machine doing most of my work. Which is kind of boring, because I really miss AmigaOS, and Cubic IDE. At times I've been working in AmigaOS, and constantly checking in the code to Subversion, and checking it out in Linux and building it there. Somewhat cumbersome, but it sort of works. I've tried various FTP syncing solutions, but the SVN solution has the advantage that I regularly check in the code!

söndag 17 april 2016

Boys keep swinging

When running the Swing applicaiton Jaguar, the AmigaGuide reader, I got exceptions due to some missing font stuff.

Light vs. heavy

When opening a Swing GUI, Swing draws all the interface components, buttons, lists, text input strings, etc, on its own. So on each platform, be it Windows, MacOS or AmigaOS, a Swing GUI would look the same. This can be compared to AWT where all the buttons are drawn by the operating system, meaning that an AWT application looks like a Windows application on Windows, and an AmigaOS application on AmigaOS. This should mean that implementing Swing requires less coding for each new platform -- if a platform can draw lines and boxes, it can also draw Swing applications, whereas to support AWT, someone would have to map each AWT button to, in our case, an intuition button. And repeat this for radio buttons, tabs, lists, text input string, etc. Usually Swing components are defined as a lightweight, and AWT componenets are heavyweight.

In GNU Classpath there exists implementations for the Swing stuff for various backends, such as GTK, X and QT. The font exception I got for Swing, is due to the Amiga implementation currently only returning "null" for some of these things. And, since Swing has to draw everything on its own, it also has to know what a font looks like. In the GTK/X/QT implementations this is handled by calling each frameworks native methods for that stuff (this is stuff like how many pixels wide the font is, where the baseline is, etc.). There is however a non-native font implementation in GNU Classpath called OpenTypeFont. This implementation actually reads the entire font file, and calculates the different font metrics in Java -- meaning I don't have to create native calls down to Amiga's font handling stuff (bullet.library, diskfont.library, etc), but instead rely on the Java implementation to read the TrueType fonts we usually have in Fonts:_ttf/.
Now, the OpenTypeFont implementation uses something called MappedByteBuffer's. A MappedByteBuffer is like a normal buffer of bytes, however backed by an actual file. The advantage of a MappedByteBuffer is that we can open a file, map it to memory, and pretend that we've read the entire file into memory, although we actually haven't. When the Java application reads a byte from the buffer, the underlying operating system will make sure that stuff is read from the file. Font files can be pretty large, so that's motivation behind using MappedByteBuffer's in this case -- we don't have to put the entire file in memory.

In order to implement MappedByteBuffer's, the Unix/Linux/Windows implementation uses mmap(), which does exactly what we want -- map a file to memory. There is an AmigaOS 4 equivalent in exec.library, the MMU interface called MapMemory. This is however:

       extremely dangerous to use if you don't know what
       you're doing. And since the virtual addressing architecture is
       not publically documented, you do *NOT* know what you're doing.
       If in doubt, don't use this function, and rely on ExecSG to do the job.

Hmpf.

Anyhow, with some helpful pointers from fellow amigans at support.amigaos.net, I've actually gotten some sort of mapped byte buffer implementation in place. I'm currently simply reading the entire file into memory, and then I just reat like an ordinary byte buffer. So I've basically removed all the perks of the MappedByteBuffer. But now atleast the OpenTypeFont implementation happily reads the fonts!
But, of course, this isn't enough. When I run the Jaguar application, a windows do open, but it's oh so empty. I'm not very surprised, since the Swing implementation on Amiga isn't done. One could illustrate it like a painter standing with a brush, eagerly waving in the air, with no paint on the brush, and no canvas in sight.

Either way, I, like the boys, keep swinging.


lördag 19 mars 2016

Swing it, magistern!

Finally motivated by some inquiring posts on amigans.net, and a donation, I've found some time to continue my Jamiga works. I'm now focusing on AWT/Swing. So, swing it magistern!

This is Alice Babs, Sweden's (late) most famous be-bop-a-doodelidoo-scat singer. She swings it good.

I've setup a Trello board, mostly for my own peronsal use. I've found that given my sometimes rather long pauses, I tend to forget what I've done. So I'm trying this Trello out, where I'll create cards under "Doing" for the tasks I'm currently doing, and adding what else I might come up with under "To do". Hopefully I'll be able to keep it updated.
If you register for Trello, I think its possible to comment and vote and stuff.

Currently there are two cards under "doing": "Fix current AWT/Swing implementation", and "Fix IntuiFontPeer". The latter being more exactly what I'm doing, and the former being the greate context why I'm doing the latter. In the "done" department we have "Find Swing/AWT application to run", which is done. The result was the oh so exciting Swing application "Jaguar". Jaguar is a Java AmigaGuide reader, using Swing.

Screenshot from Linux.
Hardly the killer app AmigaOS needs, but it starts, and has a GUI. Written in 1998 it uses the deprecated imports "com.sun.java.swing", instead of "newer" "javax.swing". After a quick find & replace, Jaguar could be compiled and run with JAmiga. It does however, of course, throw errors and can't actually be run. But that's what the Trello cards are about. (One more thing to note about Jaguar is that it can't be used, since there's a few exception when clicking the AmigaGuide buttons... but that's really just a minor detail. After all we have MultiView.)

fredag 30 oktober 2015

Mind sweeped

Today I'm playing a game of Minesweep. I never really got the hang of that game, but I'm hoping that one day we might be able play some more intriguing games. On the Amiga, using JAmiga!

So, yes, I've finally managed to get the existing AWT functionality working! Much of this is not my code, but created like ten years ago (!) by the original JAmiga developer, Peter Werno. There were a few issues that kept it from running using the new JamVM, and otherwise updated code, but I've finally got the original demos to work.

Volatile

There were a few synchronization issues, which didn't happen before. One minor, easy quick fix, was to add the word "transient", I mean "volatile" to the running flag of the window listener thread. This is how it works: the main Java thread wants to open a window. Then a new "window listener" thread is started, which actually opens the window. In order for the main thread to know when the window has been opened, it polls and loops for a flag to be set to true by the window listener thread.

// main thread waits for(ever) for running to be true 
MainThread::startGUI() {
   new WindowListenerThread().openWindow();
   while(running == false) {
     // do nothing
   }
}

...
// window listener notifies "object" when opened
WindowListenerThread::openWindow() {
   window.open();
   running = true;
}

In the old code, this was a normal boolean flag, not marked with special word "volatile". "Volatile" means that the variable can be changed by more than one thread, and, if you don't mark it that way, the JVM can make clever assumptions if it thinks that this variable isn't going to change. This means that if the main thread keeps looping and looking at it, the flag will, most of the times, be false. Even though it will take like no time to open that window, the loop will probably have made quite a few loops, and thus, in order to optimize and get a snappier Java experience, instead of actually fetching the value of the flag each time, the JVM assumes it is always false. And this is all according to the specifications and the way Java works. Previously the JVM didn't make this clever assumption (or if it was the old Java compiler that didn't make them).

I also added some synchronization around these parts, so instead of a constant loop, the loop is synchronized, meaning it checks the flag, and then waits to be notified from the window listener thread, and only then checks the flag.

// main thread waits for "object" to be notified
MainThread::startGUI() {
   new WindowListenerThread().openWindow();
   while(running == false) {
      object.wait();
   }
}

...

// window listener notifies "object" when opened
WindowListenerThread::openWindow() {
   window.open();
   running = true;
   object.notify();
}

This synchronization (the notify() and wait() methods) are part of the Java standard, and used all over the place. And when looking at it for the AWT stuff, I found some things in my implementation that were not quite working. I've known that the synchronization and signalling parts have had some glitches, so that signals sometimes aren't received as they should, leading the JVM to a halt. I knew I was taking a few shortcuts before, but now I'm pretty confident it works according to specification, since I this time actually carefully read the specifications... And, I've also been able to verify that it seems to work better, since I actually now use JAmiga to compile Java code when I'm developing JAmiga on my X1000. We kind of almost have a Java implementation so we can build Java ourselves on the Amiga!
Edited: of course I meant volatile, not transient

So, all the graphics is done now?

Now, this doens't mean that the graphics are all done, and that we can download NetBeans and run it. There's still quite a few unimplemented methods in the JAmiga specific AWT-packages. But it's getting there!

onsdag 7 oktober 2015

Software Freedom Day!

Saturday the 19th september I travelled to Uppsala, on Software Freedom Day, where Uppsala Linux User Group had an event. I was invited to talk about Jamiga: Java on Amiga.

You can see it below. It's in Swedish, but there are subtitles in English.

A big thanks to ULUG and Josef Andersson for inviting me, and special kudos to Joel Edberg for filming and doing the editing!

Besides me babbling about JAmiga, there were also talks on how open source software is used at SVT (the Swedish public service television), a talk about Gnome and a series of interviews on how open source products are used at various Swedish startups. Very interesting stuff indeed! Also, not to forget the beer and wine at a local pub afterwards. Nice to meet some Amiga folks IRL.

lördag 21 mars 2015

Interesting platform, but missing implementation here

In my last blog entry (which was ages ago, I know!), I bragged about my OpenJDK efforts. Or bragged is perhaps not the word, but, I mentioned it. I sadly haven't had time to do much about OpenJDK lately, or my Amiga for that matter. But now things at work, and in my new house (yay!) are starting to go back to normal, giving me some time to tinker with JAmiga and OpenJDK.

And this is what I'm currently greeted with:

"Interesting platform, but missing implementation here". Ha! If they only knew...

Interesting platform

My AmigaOne X1000 is currently abroad for a physical check-up, but meanwhile I've been busy with my Ubuntu laptop. I managed to compile a working adtools setup with the help of salass00 guide excellent guida at os4coding.net. It wasn't that hard to do, if you just follow the instructions. However, the GCC version currently in trunk cannot be built (March 2015), so you should instead use the 4.9.x tag. At step 5, "Build and install gcc", you have to alter "gcc-build/Makefile" which points to "gcc-trunk", and "trunk", and change this to "gcc-4.9.x" and "4.9.x", respectively. And you must have checked out the 4.9.x branch from SVN.

With the adtools cross-compiler suite up and running, I've begun my porting efforts. I've done this before, both trying the IcedTea OpenJDK project, and vanilla OpenJDK 7 and 8. My current focus is however on OpenJDK 9, without any iced tea -- just regular coffee (currently mostly decaf though, or perhaps just disgusting brown water). OpenJDK isn't released or done yet. If I understand the OpenJDK procedures correctly, each big version (i.e. 9), has a number of sub projects working on different aspects of OpenJDK. The project "Jigsaw" is my aim at the moment. I've talked about Jigsaw previously, referring to it as an onion, in short it aims to modularise OpenJDK. My hope is that I'll initially will get away with just porting the "java base" stuff, and then iteratively proceeding with the rest of Java. For the GNU classpath this is already possible, with its different libraries for javalang, javanet, and so on. OpenJDK in essence only has one big java-library. It is possible to disable stuff like AWT and such in OpenJDK, but in order to skip f.i. the java-net stuff, I would have to write dummy functions in order to make it compile. But with Jigsaw, the idea is to be able to disable entire modules, where java-net is one.

Missing implementation

Now, going back to the error message above. I know the reason for it, and I sort of knows what's needed. And its quite a lot. The error relates to "hotspot", which is OpenJDK's virtual machine -- where I want to use "JamVM". So, I can either try to implement support for hotspot, or try and adapt the build process to skip hotspot. It is possible to build OpenJDK without hotspot, if you use IcedTea. But IcedTea currently only supports OpenJDK 8. And, IcedTea needs some adaptation to support AmigaOS as well. So I think I'm doing the right thing going for OpenJDK 9. Hopefully.

lördag 28 juni 2014

Amiga+OpenJDK

In today's picture you can actually see AmigaOS running OpenJDK! Well, at least starting it.

The error you see in the grab is due to missing native libraries. What you actualy see is the latest version of JamVM starting, using OpenJDK 9 class files -- there's no Amiga specific code in there yet.

My next step is ofcourse to compile an OpenJDK version of java.library. I've begun the process on an Ubuntu installation with a PowerPC cross-compiler. I'll probably try to move the current JAmiga native library "framework" into the OpenJDK build process, and then iteratively move, refactor and adapt the current GNU Classpath Amiga implementation. It sounds straight forward enough, but its going to take a while.

But its a start.