[net.micro.mac] Multi-Processing Basics for a *real* multi-processing system.

dillon@CORY.BERKELEY.EDU (Matt Dillon) (10/16/86)

>   OK Guru's let's have it! What is envolved with a multitasking O/S for the
>Mac? No snide remarks to the effect that it can't be done, let's assume it
>can but will be slow.

	There are two basic problems with multi-tasking running MAC generic 
	programs that I see (note: I have limited knowlege of the MAC's OS):

	(1) Many programs take over the display and write to screen memory
	directly rather than openning a simple window.  This means that no
	other task would be able to use the screen.

	(2) The memory allocation scheme doesn't seem to be geared to
	multiple tasks.

	Thus, I don't think it will be possible to make the MAC into a 
	multi-tasking machine and still have it run programs written for
	the current OS.  Of course, you could create a completely new MAC
	box with an MMU and 68010 and build a multi-tasking OS on top
	of that.  With the MMU, you could manage several tasks that
	think they are running on a normal mac and trying to write to
	'THE SCREEN' at the same time by causing a fault to occur on writes 
	to screen memory and then doing some funny stuff with the fault
	handler.

----
	Assuming you don't care about compatibility with older programs,
	and redesign the operating system from scratch, it can be done.

	Hell, you've just turned your MAC into an Amiga. 

>  Many Solutions, one may be
>  Menu Bar is for the system only (task info,system services,launches,etc)
>  Processes run within subscreens (we know them as windows)
>  Each process has it's own "system window" including menubar
>  Current Process window is NOT updated on task switch
>  Screen Dynamics are handled by user commands (mouse clicks, etc.)

	Basically, each task must be 'nice' to the system, and use system
calls to write to its window and use other resources rather than write there
directly.  

	In terms of your terminology: "subscreens" isn't a good word... they
really are 'windows' (I think you agree with me here).  On the Amiga, the
distinction is physical... you physically have multiple screens and each
screen may contain multiple windows. (If you ever thought the Amiga was 
slow because it had to deal with multi-tasking when writing to windows/
screens, think again: A task can open an entirely new screen which no other
task even knows about and write to it directly, without worry of conflict).

>Other Considerations
> All I/O should be Asynchronous - increase device demand by putting
>     processes to sleep if waiting for I/O
>   Is there memory protection in the hardware for segmented addressing?
>                                          dave

	Since each I/O device would be a task, this is accomplished
very easily in a multi-tasking enviroment.

LOCKS

	Most operations in a multi-tasking system are based on semaphores,
or 'locks'.  You basically have two types of locks: The SHARED lock, and
the EXCLUSIVE lock.  Thus, you can have several tasks reading some
global data structure simultaniously, but only one can write at a time.
While that *one* is writing, nobody is reading.  The lock structuring is
usually hidden by the OS so the actual task only sees normal, everyday
calls.

	The implimentation of, say, writing a text string to your window
would be:

	gain lock for your screen	
	write the text
	release lock for your screen

	So when the OS moves a window around, it gets the lock (preventing
anybody from trying to write to the screen while it's getting moved), does
the move, and then releases the lock.

	The screen lock is required as a global-locking mechanism.  If your
going to allow multiple tasks to write to a single window, then you also
need a window-lock for each window.

	Most people have the misconception that locks are slow.  Actually,
they're extremely fast when the lock is free.  On a 680x0 gaining a free
lock takes exactly two instructions: A test-and-set and a branch.  When the
lock isn't free (the branch fails), and you have to block anyway.

COMMUNICATION

	In a Multi-tasking enviroment, tasks must be able to communicate
with each other.  Since IO will be asyncronous, you want most things to
work via QUEUES.  You want to know when an operation has completed, and
that can be accomplished by having the task on the other end send your
message back (or acknowlege it) to you via a reply port.  Advantages:

	(1) You can queue several operations and then do other things while
	the device is working on them.

		Example: You can queue disk writes for the 'capture' mode
		on your terminal program so the display doesn't get jerky
		when it dumps to the file.

	(2) The communications medium allows passing of pointers to buffers
	rather than the buffers themselves.  Thus, you can pass around
	data buffers without doing copy operations.

	(3) The communications medium can be used for other inter-process
	communication (say, between two programs working in cooperation).


SIGNALS
	Usually an integral part of the communication system. To be able to
	Wait() for one or bits from a bit mask to be set via some other 
	process:

	(1) Signal when there is a message ready on some message port
	(2) Signal keyboard keystrokes
	(3) Any Other event.

	Usually, you have most incomming events come to your task via a single
	port and a single signal.  For instance, in a typical terminal program
	you might:

		PORT1 Signal1	-keyboard/mouse_clicks/window_resize/menu
		PORT2 Signal2	-data present on serial port (note: serial
				 device will queue the data so you need not
				 process on a character-by-character basis)
		PORT3 Signal4	-BREAK pressed (or something like that).

	The other signals... asyncronous file writes, etc... are usually 
	hidden from the programmer so he simply uses normal OS calls to
	write to files etc....


							-Matt