Revisiting GEM For The Atari ST, Part 8

After part 7 of this series came out, I got some interesting feedback and a question in particular stood out. Milan Kovac asked how did MiNT handle things differently regarding applications waiting for evnt_multi() to return?

To clarify, he’s referring to MultiTOS, of which MiNT was the core, and how GEM AES behaved differently in that environment.

That question was sort of out of the scope of the original topic, but it got me thinking and I realized it sort of touched on a few other issues with AES we hadn’t talked about yet.  So here we go, and Milan, if you read through the whole thing your question gets answered eventually.

On a side note… when I write these articles, I often have the GEM source code open in a window in the background so that I can make sure I’m not remembering something incorrectly. Once again I’ve noticed how the original GEM source code is very terse and poorly commented. Function names are generally no more than 6 or 7 characters long, even with an underscore taking up a spot some where. Names of variables or structure elements are about the same. For example:

EVSPEC mwait(mask)	 	 
EVSPEC mask;	 	 
{	 	 
 rlr->p_evwait = mask;	 	 
 if ( !(mask & rlr->p_evflg) )	 	 
 {	 	 
 rlr->p_stat |= WAITIN;	 	 
 dsptch();	 	 
 }	 	 
 return(rlr->p_evflg);	 	 
}	 	 

Of course, that’s not really that unusual for code written back in those days.  But gosh, it often seems like the GEM source code takes things to extremes. Someone really ought to dump this stuff into a modern IDE and refactor the source code to give things meaningful names.

What is MiNT and MultiTOS?

Just in case anybody doesn’t know, MiNT is a multitasking kernel created by Eric Smith while he was a university student. He was trying to port over some GNU libraries and utility software to the Atari ST computers, and the problem was that the TOS operating system on the Atari was lacking certain functionality required by the code.  At first, he modified the individual GNU programs and libraries as needed, but eventually decided that instead of changing the libraries and programs, it’d be easier overall to create an extension to TOS to add the required functions. MiNT was the result.

Originally the name stood for MiNT Is Not TOS.  It basically hooked into the BIOS and GEMDOS and provided the ability to do preemptive multitasking, among other things.

MiNT caught the attention of the programmers in the TOS development group at Atari Corp., including Allan Pratt, the programmer who maintained the GEMDOS portion of TOS. He was impressed with MiNT and eventually started talking with Smith about incorporating it into a new, preemptive multitasking version of TOS. Smith was later hired by Atari in 1992, and in 1993, after a more work on everything, MultiTOS was released.

Now the name stood for MiNT Is Now TOS.

Unfortunately, the release of MultiTOS came only shortly before Atari decided to focus all of its development efforts on the new Jaguar game console, effectively ending the active life cycle of the ST computer series.  But that’s a story for another day.

Multitasking 101

Let’s cover a couple of basic concepts regarding multitasking that we haven’t talked about before, or to refresh your memory briefly.

There are two main types of multitasking, cooperative and preemptive.  Task switching is what we call it when the system stops one program’s execution and starts another one. Task switching back and forth quickly enough makes it look like all the programs are actually running at the same time. And in fact, on a modern computer with multiple processor cores, your programs probably are actually running at the same time.

Vanilla GEM features cooperative multitasking. “Cooperative” means that the system doesn’t automatically switch from one program to the next. Programs have to cooperate by doing some specific operation before task switching occurs. In vanilla GEM, that specific operation is making a call to the AES event library. Every time a GEM application calls an event library function, it may end up waiting for the event to occur, and it may end up waiting for other applications as well.

MiNT features the other flavor, preemptive multitasking.  The main thing that’s different about preemptive multitasking is that the program doesn’t have to do anything special to facilitate task switching.  It can happen at any time, regardless of what the program is doing at the moment. (There are exceptions to that which we’ll ignore for now.)

Under a preemptive multitasking system, each program, also known as a process, has at least one thread, which is what we call a distinct piece of code being executed.  A process may own more than one thread, but it always has at least one.

Preemptive multitasking systems typically operate using a timer-based interrupt.  Each thread is given a certain maximum amount of time to execute before the system stops it and gives control to another thread. Each chance that a thread gets to run is called a “time slice“.

There are a couple of things that can happen to make a thread end its time slice early, or to make the system skip a turn for a particular thread.  For example, a threads can voluntarily end its time slice early.  There are a variety of reasons it might do this, but waiting for an asynchronous task to finish is a common example. Threads can also choose to sleep and wait for a certain amount of time to pass.  This is a bit different from simply ending a time slice, as it also means that the system will skip past that thread for future time slices, until the requested duration has passed.

It’s also possible for a thread to be blocked waiting for a semaphore or MUTEX (mutually exclusive) object.  These are software mechanisms that are used to allow a thread to wait for a certain condition, or to control access to something in the system that can only be safely accessed by one thread at a time.  A good example would be something trying to send data to the printer port.  If you had several programs trying to send output to the printer at the same time, the result would be a lot of wasted time and paper.

The idea of a MUTEX is that a process has to ask for exclusive access to such items before it can use them.  Upon receiving such a request, the system will then do one of the following:

  • Grant access if the requested item is currently available. The item now belongs to the requesting process until it releases it or until that process ends.
  • If the item is already in use by another process, then the system will block the thread until the item is released.  In some cases, you can optionally have the system return an error indicating that the item is not currently available.

All this means that threads don’t always execute in the same order and frequency. It’s not always A-B-C-A-B-C, etc. It actually gets even more complicated when you consider things like thread priority settings, but that’s another left turn down this tangental road so let’s not.

There are many other important aspects to multitasking, but they are pretty much beyond the scope of this article.

GEM Applications Under Vanilla GEM

Under vanilla GEM, the core of the cooperative multitasking system was contained in the AES event library.  Whenever program “A” calls an event library function like evnt_multi, and there’s no event of the requested type in the queue waiting to be processed, the event library calls a dispatcher function that checks to see if events are waiting for any other GEM applications, and if so, performs a task switch.

That is, incidentally, the purpose of the mwait function shown above as an example of the GEM source code. As simple as it is, that function is where GEM makes the decision to pass control back to the same program, or task switch to another.  It’s called by each of the various public functions of the AES event library, like evnt_multi or evnt_mouse and so forth.

The mask parameter indicates the types of events the application is requesting, and this function compares that against the events that are available.  If nothing is available, it calls the dsptch function, which is responsible for vanilla GEM AES’s cooperative task switching.

If the dspatch function found events waiting for program “B”, which by definition in vanilla GEM would currently be waiting for an event library function to return, then it would perform a task switch to that application so the events could be processed. Eventually, program “B” would make another call to an event library function, and maybe this time program “A” gets control back, or perhaps program “C” is called instead, depending on what’s waiting in the queue of unprocessed events. In this way, all of the applications currently loaded into the system would get a chance to process their events and interact with the user.

This sort of task switching is essentially the same general process that’s used by preemptive multitasking systems, except that it relies on programs making calls to the AES event library. Note that non-GEM applications couldn’t be included in this setup, since they don’t make calls to the event library. Whenever you ran a non-GEM application, it essentially blocked GEM applications until it exited.

GEM Applications Under MultiTOS (MiNT)

A well-designed GEM application that handles events properly and doesn’t try to draw to parts of the screen that it doesn’t “own” should work fine under MultiTOS.  In fact, programs which occasionally need to suspend event processing while doing something else will arguably work better under MultiTOS, since they will no longer freeze up the whole system.  The program’s own UI will be blocked until it starts making event library calls again, but other programs will continue to operate normally.

But as to how it works…

Quite a lot about GEM AES was changed for MultiTOS, but we’re only going to talk about certain things here.

Under MultiTOS, the MiNT kernel is now responsible for handling task switching between applications, rather than the AES event library.  Each application has at least one thread, including non-GEM applications.  Additionally, the AES maintains its own process that corresponds to the “original” single process in vanilla GEM, which is responsible for managing the user’s interaction with UI elements like the menu bar, window frames, etc.

So, if the event library is no longer doing its own task switching, what happens if program “A” calls the event library to request an event, and the desired event is not available?

Instead of doing its own task switch, AES will tell MiNT “I’m done for now” for the current thread’s time slice, prompting MiNT to perform a task switch.  The AES code is actually shorter and more simple than under vanilla GEM.

On the next time slice for program “A”, the first thing it will do is check again to see if the desired event is available. If not, then it will once again release the time slice. This will repeat until the event becomes available. Thus, programs which are waiting for events use very little CPU time; just enough to see if there are events pending.

AES MUTEX Items

We talked about MUTEX items earlier. While it doesn’t use that terminology, GEM AES has always had something that acts as a MUTEX, and it’s something all GEM programmers should know about.  When an application does a window update, the process is wrapped with calls to wind_update. This is intended to block any other application from starting a window update while another one is already happening.  It’s intended to provide exclusive access to the screen to a single application at a time.

To accomplish this, the original vanilla GEM code for wind_update ties into the event library.  It adds a special “mutex released” item to the list of requested events so that ending the update has to occur before another application can be called.

Under vanilla GEM, the wind_update function didn’t actually check to see if an application had locked down the screen.  It relied solely on the mutex event to block other applications from being able to do anything, since they wouldn’t be running until AES had events for them to process. However, under MultiTOS, another application might not have been waiting for an event to occur.  In that case, the application will keep on doing whatever it was doing. Unfortunately, this could eventually include a window refresh, so under MultiTOS, the wind_update call gets significantly more complicated than it was under vanilla.

Don’t Cross The Beams!  Whoops!

Finally, we’ve come around to another flaw in vanilla GEM AES.  From day one, GEM was supposed to be a multitasking system, but other than using the wind_update function to manage, somewhat imperfectly, screen output, it didn’t include any sort of a general purpose MUTEX or semaphore library so that applications could avoid stepping on each other when they all wanted to use the same resources at the same time.

It always amazed me that this was never revealed to be the big problem it had the potential to be.  I guess users were really just so used to interacting with just program at a time that it rarely came up. But consider how many things in the system could fail if more than one application wanted access.  Just to name a few:

  • Serial ports.  What if you had a FAX program and a telecommunications terminal program going at the same time?  One as the main application, the other as a desk accessory?  Until the Mega STE and TT030 machines, there was only one serial port so this would have definitely resulted in a conflict as both programs tried to access the same port and modem at the same time.
  • Printer port.  Two programs trying to print something at the same time could step on each other unless both were doing it through GDOS.  In that case, well, frankly, I dunno what would have happened.  I’d like to think that they would have been able to do a page at a time per program, but I’m not sure.
  • MIDI ports.  Basically the same problem as the serial ports, except with different kinds of program.
  • Sound.  Sound on the ST computers was mainly done by banging on the sound chip, either directly on the hardware registers, or via the XBIOS DoSound call. Either way, two programs trying to this at the same time would result in some interesting results that would hurt your ears.

Basically, when it came to these items and other similar system resources, AES basically relied on the idea that a program would start using the item and finish it between one event library call and the next, when no other programs could be called and start trying to use the same resource.

That sounds pretty risky, but actually it more or less worked most of the time.

MultiTOS and Mutex

When MultiTOS came out, MiNT added the basic capability needed to create mutex objects, but except for defining a couple of specific hardware resources like the SCSI or ASCI ports, which were used by the system itself, there were no preset definitions for anything that applications could rely on.

Now that it had the low-level functionality to do the job, you would think that someone would have added some functions to GEM AES to do basic application-level resource management.

You’d think that, but you’d be wrong.  AES continued to ignore the problem under MultiTOS.

Sigh.

Don’t get me wrong… I loved MultiTOS when it finally got to be more or less stable, and I used it on a daily basis long before it even got to that point.

Of course,  at the time, my machine at the office was a TT030 with maxed-out RAM, and a big 320mb hard drive.  And it was reasonably useable on the Falcon030 too.  What about on the older machines running at 8 mHz?  Even with the max 4mb of RAM, I avoided ever really using that setup. So I really couldn’t tell you how badly it sucked.  I was just pretty sure it did.

And by the way, 320mb was big for a hard drive back then.  Honest.  But even so, even with a relatively nice system like what I was using, we all knew how easy it really was to do something that just plain wouldn’t work.

Maybe if Atari had kept going with development on the ST series, some of those issues would have gotten fixed.  We weren’t unaware of them, in many cases, but there was only so much we could do with the manpower and time available.  And then, of course, the Jaguar came along and we all shifted gears to focus on it.

It’s really kind of ironic, because the last two or three years worth of TOS development had seen far more improvements and new functionality added to the system than the previous six years had.

Sigh.

 

For customers who are interested in creating a blog, or who need a content management system, we usually recommend using the popular WordPress content management system.  For customers on a budget, WordPress is a great way to go because the software itself is free.

One of the greatest strengths of WordPress is the ability to use custom themes so you can customize the appearance of your website.  There are a wide variety of different themes around the web to choose from.  Some websites offer “premium” themes, but there are thousands of free themes available as well.

  • WordPress Custom Themes – We can help you select one of the many excellent free themes out there, and then customize it as needed to make it your own.  If you can’t find an existing theme that you like, we can create an entirely new custom theme for you!
  • Ultra-Customized WordPress Themes – There are a lot of great WordPress themes out there, but most of them do nothing more than change around the colors, background images, and rearrange where everything goes on screen.  They don’t offer any additional functionality.  If you need something more, then you need a theme that is customized for your specific needs.  When you need customization that goes beyond shuffling artwork, we’ve got the programming skill and experience to make your theme do whatever you need.
  • Custom WordPress Plugins – There are many plug-ins out there for WordPress that cover a lot of subjects, but if we can’t find one that does what you need, we can create it as needed!  We can even integrate customized plug-ins with your custom theme to take WordPress beyond the usual limits.

Are you lost every time you go to the store to buy a new computer? Do you need a new laptop, or a new printer, and you just don’t know which one to buy?

Let Mike Fulton Consulting help.  We’ll sit down with you and figure out which features are the most important and we’ll do the product research for you! Having the right facts before you buy makes all the difference.

We also offer custom application programming for Windows or Macintosh platforms, database programming, mobile development for Android and iOS, and much more.

If you have questions, please send EMAIL or select the Contact Mike item in the main menu. Please include details about your interest, and make sure to include complete contact information.

Big companies usually have a full-time staff of IT techs who are ready to go whenever someone around the office needs a new printer installed, or when the WiFi isn’t working, but small businesses can’t afford that luxury.

When small businesses have an IT problem, it often gets ignored because nobody knows what to do. At best, an inefficient workaround is used, hurting productivity.

Now there’s another option. Mike Fulton Consulting can be your on-demand IT staff! We can help you get new computers up and running, install printers and other peripherals, install software, and more. Give us a call!

Our main focus these days is website design and creation. If you have specific requirements, let us know and we’ll find the solution that’s best for you.  If you don’t know the specifics for your new website, talk to us and we’ll help you figure it out!

For those sites running on Microsoft-based servers, we can do custom, high-performance ASP.NET solutions.

If you’re using a Linux-based server, we can do a completely customized solution or we we can start off with a popular web content management system such as WordPressDrupal, or Joomla and customize things as needed.  Want to set up an eCommerce site and get your merchandise on the web?  We can do that too!