From: mks@cbmvax.commodore.com (Michael Sinz)
Newsgroups: comp.sys.amiga.programmer
Subject: Re: Low level context switch for tasks
Date: 13 Nov 92 15:39:10 GMT
Reply-To: mks@cbmvax.commodore.com (Michael Sinz)
Organization: Commodore, West Chester, PA

aurel@uni-paderborn.de (Aurel Balmosan) writes:
>
>I have a question about the use of the <task-switch>, <task-launch> function
>pointers in the task structure.
>First: I think the reason why the Commodore-IEEE-Math-Library must be opened
>by each task is: It install a <task-switch>,<task-launch> function to save
>and restore the registers of the Math-Copro. Is this right?

Yes, but this is only on systems where the math coprocessor is *not* a
CPU connected processor but a an I/O based one.  (Such as is required to
have a 68881 used with the 68000 or 68010 CPU.)  On systems where the
processor is directly connected (68020 and up) this is not done.

>Second: If my first question is right, how do I install more then one
><task-switch>,<task-launch> function in a way which is good for the system?

If the task flags say there is already one installed, then use the old
pointers as the routines and "chain" then.  That is, when done, call the
new ones.  For example, to install (assume you have the right locking here
and all of that...)

		move.l	d0,a1			; Task to play with...
		bset.b	#TB_LAUNCH,TC_FLAGS(a1)	; Set launch flags...
		lea	TC_LAUNCH(a1),a1	; Point at launch magic...
		beq.s	NoOldLaunch		; If bit was unset, no old launch...
*
		move.l	(a1),(a0)		; Store old launch
NoOldLaunch:	lea	CLaunch(pc),a0		; Get ours
		move.l	a0,(a1)			; Store as task's

Then, the CLaunch code looks like this:  (This one does some work
with timers which is how I do the timing in the PM program)

CLaunch:	move.l	CLaunchOld(pc),-(sp)	; Get old launch point
		bne.s	Launch_Chain		; Check for chained launch...
		addq.l	#4,sp			; Never mind the non-chained launch...
Launch_Chain:	movem.l	d0/d1/a0/a1/a6,-(sp)

		move.l	TimerBase(pc),a6	; Get timer base
		lea	LaunchTime(pc),a0	; Get lauch time pointer
		CALLSYS	ReadEClock		; Read the time...
		lea	LaunchTime+8(pc),a0	; Get time...
		lea	WaitTime+8(pc),a1	; Get total...

		moveq.l	#0,d0			; Clear X bit...
		addx.l	-(a0),-(a1)		; Add this time to the total
		addx.l	-(a0),-(a1)		; ...

		lea	SwitchTime+8(pc),a0

		addq.l	#8,a1			; Adjust back up to Time+8...
		moveq.l	#0,d0			; Clear X bit...
		subx.l	-(a0),-(a1)		; Subtract starting time
		subx.l	-(a0),-(a1)		; ...

		movem.l	(sp)+,d0/d1/a0/a1/a6
		rts				; Do old launch or return...


>The reason why I ask this questions is:
>If the system have a way to install more then one <task-switch>,<task-launch>
>function I can use the <task-switch>,<task-launch> for a low level context
>switch!

As long as everyone follows the above method, things should work just fine.
The only "trick" is that there is no safe/simple way to uninstall a
handler if some other handler installed on top of you.  Basically, you
can only remove if you are the "top" one.  (If TC_LAUNCH is pointing to
your code you just replace it with what used to be there... or turn it off
if there was none...)

>Specially: I could switch the MMU-list for each task. I think this is a way
>to virtual memory without changing any existing program to use this
>virtual memory. And the virtual memory would be dynamic!

Well, this may not work too well since you would need to keep all of the
MMU tables up to date at the same time since each task still needs to be
able to get at public data from other tasks.  The method you have talked
about here is basically what would be done for a protected memory system
but that is not really possible on the Amiga since so many different tasks
need to have access to the memory of other tasks...

>Also the system would be able to protect memory of each task. This would make
>the Amiga more stable! (If a task go wild the system would run normally!)

Well, if you think so...  It would more likely be such that 99% of all software
would not run in this state.  The reason is that to load data from the disk
requires that some task allocate memory and then pass a pointer to that memory
to the filesystem which then goes to the right scsi.device and does the reads.
That is 2 to 4 different tasks right there.  Add in things like intuition,
input.device, etc. and you get to the point that you can not protect the
memory...

/----------------------------------------------------------------------\
|      /// Michael Sinz  -  Senior Amiga Systems Engineer              |
|     ///                   Operating System Development Group         |
|    ///   BIX:  msinz      UUNET:  mks@cbmvax.commodore.com           |
|\\\///                                                                |
| \XX/     "I think not." said Ren'e Descartes, then he vanished.      |
\----------------------------------------------------------------------/
Newsgroups: comp.sys.amiga.programmer