Supporting ARM or not


#1

Last year I got in contact with a company to sponsor ARM development for Redtamarin and strangely ended up doing a whole other project, the idea was to support ARM it had to be sponsored because well… it is a lot of work.

And yeah it has been some time that I was thinking

it would be cool to run Redtamarin on a Raspberry Pi


So the other day when I have been contacted about the feasibility of compiling Redtamarin for Linux ARM, I looked a bit more into it and wrote something on the wiki: Supported Operating System - Linux on ARM.

And well it happen it is something “not that easy”.

Because Tamarin/Avmplus was setup to compile on Android ARM and WindowsRT ARM and it could compile on Linux with CPU like SH4 and MIPS, I thought it would be easier and mainly a problem of setting up a development environment that works.

Not at all :smile: .

in short look into src/nanojit/NativeARM.cpp

#ifdef NANOJIT_64BIT
#error ARM CAN'T HANDLE 64bit YET'
#endif

And so I thought about the problem some more …


Thanks to the Adobe team the Tamarin/Avmplus project setup is great to support multiple operating system under multiple architecture (eg. different type of CPU), but among all those I long abandoned the support for PPC as no more mac use that, I see not a lot of interest for Solaris, etc.

So yeah that’s why I mainly supports 3 main OS: Windows, macOS and Linux, and all on Intel CPU
and x86/i686 (32bit) and x86_64/amd64 (64bit).

Supporting ARM is possible, but is it really worth it ?

From the beginning it is something where I felt it needed funding, as someone willing to pay money to help develop it (because it is hard and take time etc.), so even if I had funding how long would it take ? How much would it cost really?

In the range of the 3 to 6 months, and so … many thousands euros/dollars.

But that’s just the raw costs to “make it works”, there are also hidden costs.

For example, each time a new feature is added to Redtamarin native API, it need to be ported to all 3 platforms: Windows, macOS and Linux.

Let’s take a simple example: getenv()

It’s part of the C standard and by extension POSIX

you can super easily implement it for Linux

const char *VMPI_getenv(const char *name)
{
    return getenv(name);
}

cherry on the cake, that same implementation will also work for macOS (or how to kill 2 bird with 1 stone).

Now we need the implementation for Windows, super easy too

const char *VMPI_getenv(const char *name)
{
    return getenv( name );
}

yep, that’s the same, but then for Windows we made a little addition to support UTF-8

const wchar *VMPI_getenv16(const wchar *name)
{
    return _wgetenv( name );
}

But still all that is super easy, really about 10mn to implement and integrate etc.

Now, in general the main problem for such implementation is the Windows side, eg. when Windows does not have a compatible POSIX function call.

Some things are considered “impossible” like fork(), well… not really impossible but really you don;t want to implement an emulated fork for Windows you woudl want to handle processes creation the Windows way and so make an abstract layer which define Process.create() and use CreateProcess().

But when it is possible, you just write the code for Windows, recently I added nice()

nice just tell your current process to be more or less nice, eg. use more or less priority on the scheduler.

a typical usage is

import C.unistd.*;

// be very nice with the CPU, eg. use a low priority
var result:int = nice( 20 );

So for both Linux and macOS the implementation is super easy

int VMPI_nice(int incr)
{
    return ::nice( incr );
}

and for Windows, well you kind of emulate the same behaviour with native Windows API

int VMPI_nice(int incr)
{
    DWORD prioclass;

    if( incr <= -20 )
    {
        prioclass = HIGH_PRIORITY_CLASS;
    }
    else if( incr < 0 )
    {
        prioclass = ABOVE_NORMAL_PRIORITY_CLASS;
    }
    else if( incr == 0 )
    {
        prioclass = NORMAL_PRIORITY_CLASS;
    }
    else if( incr >= 20 )
    {
        prioclass = IDLE_PRIORITY_CLASS;
    }
    else if( incr > 0 )
    {
        prioclass = BELOW_NORMAL_PRIORITY_CLASS;
    }
    else
    {
        prioclass = NORMAL_PRIORITY_CLASS;
    }

    BOOL result = SetPriorityClass( GetCurrentProcess(), prioclass );

    //failed
    if( !result )
    {
        errno = WIN32_error_to_errno();
        return -1;
    }

    // save the new value
    WIN32_nice = incr;
    return WIN32_nice;
}

My point?

Well … now each time I compile a new Redtamarin runtime I have to be sure

  • that getenv(), nice() etc. have the same behaviour under the 3 platforms
  • that means compiling on those 3 platforms and testing it
  • that means compiling those in 32bit and 64bit and testing it
  • etc.

Suddenly either your easy implementation of 10mn or a bit less easy (30mn) add 1h of testing.

The more functionalities you add, the more platform you target, the more difference (32bit or 64bit), the more you have to tests, document, etc. and it take more and more time.

So adding a whole new architecture like ARM, provided you want to support it only on Linux
well yeah it add a lot more time to all that.

And now, what about supporting ARM 32bit and ARM 64bit ?
And supporting ARM for Windows (eg. WindowsRT) ?
And supporting ARM for Android ?

Yep the hidden costs is time and it is exponential.

For what ?
oh so dev can easily run Redtamarin on a $20 ARM board.

Let me be clear: invest about N x $1000 of development effort to support $20 hardware.

So I thought some more …


Personally whatI like with the ARM board type, is the “hacking” parts where you connect and control sensors and other stuff, presence sensors, smoke sensors, light sensors, etc.

I personally does not give a flying fuck that the CPU is ARM, my interest is the small form factor hacking board.

I could go the way, “hey let’s emulate it”, like installing qemu-i386-static under an unbuntu-arm etc.
but this is freaking slow and so useless.

But wait a minute, see what happened in the Android world?
first you had ARM CPU and then you had x86 Intel CPU.

And look look, it’s happening also to those small form factor hacking boards
Here Come the x86 Hacker Boards

  • JaguarBoard
    price: ~$80, CPU: Intel Atom Z3735G
  • UP board
    price: $80 to $250, CPU: Intel Atom x5-Z8350
  • Udoo
    with Udoo X86
    price: from $125 to $260, CPU: Intel Pentium N3710, Intel Celeron N3160, Intel Atom X5-E8000

and there is more
Quad-core Atom based Raspberry Pi lookalike is ready to roll

Not only those boards use Intel CPU but they also adopting the Raspberry Pi’s 40-pin expansion adapter.

Either wait few months for all those boards to arrive on the market and pay more money for it (eg. $20 vs $200), or spend months and lot of money to add support for ARM in Redtamarin …

I made my choice :smile:

I will simply not add support for ARM to Redtamarin.

Not that I dislike ARM or Raspberry Pi, but in term of time/costs investment,
really … not worth it.


ARM32 compiling results
ARM64 compiling results