Re: [hatari-devel] Microwire register value on Falcon

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Hi,

On lauantai 04 helmikuu 2012, Nicolas Pomarède wrote:
> Interrupt handling in cycint.c is one of the most used part in the
> emulation, it's called each time a CPU instruction is processed ; the
> smaller we keep the possible interrupts list, the faster this list is
> reordered when an interrupt happens.

If I remember right, in ST emulation interrupt handling takes most CPU
after display updating.  If one uses frameskip, then interrupt handling
is the main CPU sink, especially if one doesn't use the timer-d thing.

It's not so nice that Falcon emulation slows ST emulation, even when
it's not enabled. :-/


Btw. I was thinking that the "pFunction" member in INTERRUPTHANDLER
is superfluous and and that compiler might be able to optimized checking
all members of a bool array better than checking struct array bool
members.  With such changes, there are much less data holes for CPU
cache.  If that indeed is faster, maybe something like attached patch
could be considered for the Hatari v1.7? :-)


	- Eero
diff -r be02d6922a06 src/cycInt.c
--- a/src/cycInt.c	Fri Feb 03 23:56:20 2012 +0200
+++ b/src/cycInt.c	Sat Feb 04 00:50:39 2012 +0200
@@ -96,16 +96,9 @@
 	Midi_InterruptHandler_Update
 };
 
-/* Event timer structure - keeps next timer to occur in structure so don't need
- * to check all entries */
-typedef struct
-{
-	bool bUsed;                   /* Is interrupt active? */
-	Sint64 Cycles;
-	void (*pFunction)(void);
-} INTERRUPTHANDLER;
 
-static INTERRUPTHANDLER InterruptHandlers[MAX_INTERRUPTS];
+static bool InterruptUsed[MAX_INTERRUPTS];
+static Sint64 InterruptCycles[MAX_INTERRUPTS];
 static int ActiveInterrupt=0;
 
 static void CycInt_SetNewInterrupt(void);
@@ -126,48 +119,14 @@
 	/* Reset interrupt table */
 	for (i=0; i<MAX_INTERRUPTS; i++)
 	{
-		InterruptHandlers[i].bUsed = false;
-		InterruptHandlers[i].Cycles = INT_MAX;
-		InterruptHandlers[i].pFunction = pIntHandlerFunctions[i];
+		InterruptUsed[i] = false;
+		InterruptCycles[i] = INT_MAX;
 	}
 }
 
 
 /*-----------------------------------------------------------------------*/
 /**
- * Convert interrupt handler function pointer to ID, used for saving
- */
-static int CycInt_HandlerFunctionToID(void (*pHandlerFunction)(void))
-{
-	int i;
-
-	/* Scan for function match */
-	for (i=0; i<MAX_INTERRUPTS; i++)
-	{
-		if (pIntHandlerFunctions[i]==pHandlerFunction)
-			return i;
-	}
-
-	/* Didn't find one! Oops */
-	fprintf(stderr, "\nError: didn't find interrupt function matching 0x%p\n",
-	        pHandlerFunction);
-	return 0;
-}
-
-
-/*-----------------------------------------------------------------------*/
-/**
- * Convert ID back into interrupt handler function, used for restoring
- */
-static void *CycInt_IDToHandlerFunction(int ID)
-{
-	/* Get function pointer */
-	return pIntHandlerFunctions[ID];
-}
-
-
-/*-----------------------------------------------------------------------*/
-/**
  * Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
  */
 void CycInt_MemorySnapShot_Capture(bool bSave)
@@ -177,34 +136,36 @@
 	/* Save/Restore details */
 	for (i=0; i<MAX_INTERRUPTS; i++)
 	{
-		MemorySnapShot_Store(&InterruptHandlers[i].bUsed, sizeof(InterruptHandlers[i].bUsed));
-		MemorySnapShot_Store(&InterruptHandlers[i].Cycles, sizeof(InterruptHandlers[i].Cycles));
-		if (bSave)
-		{
-			/* Convert function to ID */
-			ID = CycInt_HandlerFunctionToID(InterruptHandlers[i].pFunction);
-			MemorySnapShot_Store(&ID, sizeof(int));
-		}
-		else
-		{
-			/* Convert ID to function */
-			MemorySnapShot_Store(&ID, sizeof(int));
-			InterruptHandlers[i].pFunction = CycInt_IDToHandlerFunction(ID);
-		}
+		MemorySnapShot_Store(&InterruptUsed[i], sizeof(InterruptUsed[i]));
+		MemorySnapShot_Store(&InterruptCycles[i], sizeof(InterruptCycles[i]));
 	}
 	MemorySnapShot_Store(&nCyclesOver, sizeof(nCyclesOver));
 	MemorySnapShot_Store(&PendingInterruptCount, sizeof(PendingInterruptCount));
 	if (bSave)
 	{
-		/* Convert function to ID */
-		ID = CycInt_HandlerFunctionToID(PendingInterruptFunction);
+		ID = 0;
+		/* Scan for function match */
+		for (i=0; i<MAX_INTERRUPTS; i++)
+		{
+			if (pIntHandlerFunctions[i] == PendingInterruptFunction)
+			{
+				ID = i;
+				break;
+			}
+		}
+		if (!ID)
+		{
+			/* Didn't find one! Oops */
+			fprintf(stderr, "\nError: didn't find interrupt function matching 0x%p\n",
+				PendingInterruptFunction);
+		}
 		MemorySnapShot_Store(&ID, sizeof(int));
 	}
 	else
 	{
 		/* Convert ID to function */
 		MemorySnapShot_Store(&ID, sizeof(int));
-		PendingInterruptFunction = CycInt_IDToHandlerFunction(ID);
+		PendingInterruptFunction = pIntHandlerFunctions[ID];
 	}
 
 
@@ -237,19 +198,19 @@
 	for (i = INTERRUPT_NULL+1; i < MAX_INTERRUPTS; i++)
 	{
 		/* Is interrupt pending? */
-		if (InterruptHandlers[i].bUsed)
+		if (InterruptUsed[i])
 		{
-			if (InterruptHandlers[i].Cycles < LowestCycleCount)
+			if (InterruptCycles[i] < LowestCycleCount)
 			{
-				LowestCycleCount = InterruptHandlers[i].Cycles;
+				LowestCycleCount = InterruptCycles[i];
 				LowestInterrupt = i;
 			}
 		}
 	}
 
 	/* Set new counts, active interrupt */
-	PendingInterruptCount = InterruptHandlers[LowestInterrupt].Cycles;
-	PendingInterruptFunction = InterruptHandlers[LowestInterrupt].pFunction;
+	PendingInterruptCount = InterruptCycles[LowestInterrupt];
+	PendingInterruptFunction = pIntHandlerFunctions[LowestInterrupt];
 	ActiveInterrupt = LowestInterrupt;
 
 	LOG_TRACE(TRACE_INT, "int set new out video_cyc=%d active_int=%d pending_count=%d\n",
@@ -269,13 +230,13 @@
 	/* Find out how many cycles we went over (<=0) */
 	nCyclesOver = PendingInterruptCount;
 	/* Calculate how many cycles have passed, included time we went over */
-	CycleSubtract = InterruptHandlers[ActiveInterrupt].Cycles - nCyclesOver;
+	CycleSubtract = InterruptCycles[ActiveInterrupt] - nCyclesOver;
 
 	/* Adjust table */
 	for (i = 0; i < MAX_INTERRUPTS; i++)
 	{
-		if (InterruptHandlers[i].bUsed)
-			InterruptHandlers[i].Cycles -= CycleSubtract;
+		if (InterruptUsed[i])
+			InterruptCycles[i] -= CycleSubtract;
 	}
 
 	LOG_TRACE(TRACE_INT, "int upd video_cyc=%d cycle_over=%d cycle_sub=%lld\n",
@@ -295,13 +256,13 @@
 	CycInt_UpdateInterrupt();
 
 	/* Disable interrupt entry which has just occured */
-	InterruptHandlers[ActiveInterrupt].bUsed = false;
+	InterruptUsed[ActiveInterrupt] = false;
 
 	/* Set new */
 	CycInt_SetNewInterrupt();
 
 	LOG_TRACE(TRACE_INT, "int ack video_cyc=%d active_int=%d active_cyc=%d pending_count=%d\n",
-	               Cycles_GetCounter(CYCLES_COUNTER_VIDEO), ActiveInterrupt, (int)InterruptHandlers[ActiveInterrupt].Cycles, PendingInterruptCount );
+	               Cycles_GetCounter(CYCLES_COUNTER_VIDEO), ActiveInterrupt, (int)InterruptCycles[ActiveInterrupt], PendingInterruptCount );
 }
 
 
@@ -318,15 +279,15 @@
 	if ( ActiveInterrupt > 0 )
 		CycInt_UpdateInterrupt();
 
-	InterruptHandlers[Handler].bUsed = true;
-	InterruptHandlers[Handler].Cycles = INT_CONVERT_TO_INTERNAL((Sint64)CycleTime , CycleType) + nCyclesOver;
+	InterruptUsed[Handler] = true;
+	InterruptCycles[Handler] = INT_CONVERT_TO_INTERNAL((Sint64)CycleTime , CycleType) + nCyclesOver;
 
 	/* Set new active int and compute a new value for PendingInterruptCount*/
 	CycInt_SetNewInterrupt();
 
 	LOG_TRACE(TRACE_INT, "int add abs video_cyc=%d handler=%d handler_cyc=%lld pending_count=%d\n",
 	          Cycles_GetCounter(CYCLES_COUNTER_VIDEO), Handler,
-	          (long long)InterruptHandlers[Handler].Cycles, PendingInterruptCount );
+	          (long long)InterruptCycles[Handler], PendingInterruptCount );
 }
 
 
@@ -353,14 +314,14 @@
 		CycInt_UpdateInterrupt();
 
 //  nCyclesOver = 0;
-	InterruptHandlers[Handler].bUsed = true;
-	InterruptHandlers[Handler].Cycles = INT_CONVERT_TO_INTERNAL((Sint64)CycleTime , CycleType) + PendingInterruptCount;
+	InterruptUsed[Handler] = true;
+	InterruptCycles[Handler] = INT_CONVERT_TO_INTERNAL((Sint64)CycleTime , CycleType) + PendingInterruptCount;
 
 	/* Set new */
 	CycInt_SetNewInterrupt();
 
 	LOG_TRACE(TRACE_INT, "int add rel no_off video_cyc=%d handler=%d handler_cyc=%lld pending_count=%d\n",
-	               Cycles_GetCounter(CYCLES_COUNTER_VIDEO), Handler, InterruptHandlers[Handler].Cycles, PendingInterruptCount );
+	               Cycles_GetCounter(CYCLES_COUNTER_VIDEO), Handler, InterruptCycles[Handler], PendingInterruptCount );
 }
 #endif
 
@@ -383,15 +344,15 @@
 	if ( ActiveInterrupt > 0 )
 		CycInt_UpdateInterrupt();
 
-	InterruptHandlers[Handler].bUsed = true;
-	InterruptHandlers[Handler].Cycles = INT_CONVERT_TO_INTERNAL((Sint64)CycleTime , CycleType) + CycleOffset;
+	InterruptUsed[Handler] = true;
+	InterruptCycles[Handler] = INT_CONVERT_TO_INTERNAL((Sint64)CycleTime , CycleType) + CycleOffset;
 
 	/* Set new active int and compute a new value for PendingInterruptCount*/
 	CycInt_SetNewInterrupt();
 
 	LOG_TRACE(TRACE_INT, "int add rel offset video_cyc=%d handler=%d handler_cyc=%lld offset_cyc=%d pending_count=%d\n",
 	          Cycles_GetCounter(CYCLES_COUNTER_VIDEO), Handler,
-	          (long long)InterruptHandlers[Handler].Cycles, CycleOffset, PendingInterruptCount);
+	          (long long)InterruptCycles[Handler], CycleOffset, PendingInterruptCount);
 }
 
 
@@ -406,14 +367,14 @@
 	CycInt_UpdateInterrupt();
 
 	/* Stop interrupt after CycInt_UpdateInterrupt, for CycInt_ResumeStoppedInterrupt */
-	InterruptHandlers[Handler].bUsed = false;
+	InterruptUsed[Handler] = false;
 
 	/* Set new */
 	CycInt_SetNewInterrupt();
 
 	LOG_TRACE(TRACE_INT, "int remove pending video_cyc=%d handler=%d handler_cyc=%lld pending_count=%d\n",
 	          Cycles_GetCounter(CYCLES_COUNTER_VIDEO), Handler,
-	          (long long)InterruptHandlers[Handler].Cycles, PendingInterruptCount);
+	          (long long)InterruptCycles[Handler], PendingInterruptCount);
 }
 
 
@@ -424,7 +385,7 @@
 void CycInt_ResumeStoppedInterrupt(interrupt_id Handler)
 {
 	/* Restart interrupt */
-	InterruptHandlers[Handler].bUsed = true;
+	InterruptUsed[Handler] = true;
 
 	/* Update list cycle counts */
 	CycInt_UpdateInterrupt();
@@ -433,7 +394,7 @@
 
 	LOG_TRACE(TRACE_INT, "int resume stopped video_cyc=%d handler=%d handler_cyc=%lld pending_count=%d\n",
 	          Cycles_GetCounter(CYCLES_COUNTER_VIDEO), Handler,
-	          (long long)InterruptHandlers[Handler].Cycles, PendingInterruptCount);
+	          (long long)InterruptCycles[Handler], PendingInterruptCount);
 }
 
 
@@ -444,7 +405,7 @@
 bool CycInt_InterruptActive(interrupt_id Handler)
 {
 	/* Is timer active? */
-	if (InterruptHandlers[Handler].bUsed)
+	if (InterruptUsed[Handler])
 		return true;
 
 	return false;
@@ -459,8 +420,8 @@
 {
 	Sint64 CyclesPassed, CyclesFromLastInterrupt;
 
-	CyclesFromLastInterrupt = InterruptHandlers[ActiveInterrupt].Cycles - PendingInterruptCount;
-	CyclesPassed = InterruptHandlers[Handler].Cycles - CyclesFromLastInterrupt;
+	CyclesFromLastInterrupt = InterruptCycles[ActiveInterrupt] - PendingInterruptCount;
+	CyclesPassed = InterruptCycles[Handler] - CyclesFromLastInterrupt;
 
 	LOG_TRACE(TRACE_INT, "int find passed cyc video_cyc=%d handler=%d last_cyc=%lld passed_cyc=%lld\n",
 	          Cycles_GetCounter(CYCLES_COUNTER_VIDEO), Handler,


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/