Skip to content

Commit 0ccd265

Browse files
committed
Minor scheduler performance enhancements
1 parent f9532d2 commit 0ccd265

File tree

13 files changed

+71
-104
lines changed

13 files changed

+71
-104
lines changed

GenOpCodes/My Project/AssemblyInfo.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
3131
' by using the '*' as shown below:
3232
' <Assembly: AssemblyVersion("1.0.*")>
3333

34-
<Assembly: AssemblyVersion("2018.8.27.172")>
35-
<Assembly: AssemblyFileVersion("2018.8.27.172")>
34+
<Assembly: AssemblyVersion("2018.8.27.181")>
35+
<Assembly: AssemblyFileVersion("2018.8.27.181")>

RunTests/My Project/AssemblyInfo.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
3131
' by using the '*' as shown below:
3232
' <Assembly: AssemblyVersion("1.0.*")>
3333

34-
<Assembly: AssemblyVersion("2018.8.27.271")>
35-
<Assembly: AssemblyFileVersion("2018.8.27.271")>
34+
<Assembly: AssemblyVersion("2018.8.27.283")>
35+
<Assembly: AssemblyFileVersion("2018.8.27.283")>

x8086NetEmu/Adapters/Audio/AdlibAdapter.vb

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ Public Class AdlibAdapter ' Based on fake86's implementation
134134
audioProvider = New CustomBufferProvider(AddressOf FillAudioBuffer, SampleRate, 8, 1)
135135
waveOut.Init(audioProvider)
136136

137-
'adlibTicks = (Scheduler.CLOCKRATE / SampleRate) * waveOut.NumberOfBuffers ' FIXME: I don't think this is 100% correct
138-
'adlibTicks = (Scheduler.CLOCKRATE / SampleRate)
137+
'adlibTicks = (Scheduler.BASECLOCK / SampleRate) * waveOut.NumberOfBuffers ' FIXME: I don't think this is 100% correct
138+
'adlibTicks = (Scheduler.BASECLOCK / SampleRate)
139139
'lastAdlibTicks = Long.MaxValue
140140

141141
waveOut.Play()
@@ -194,10 +194,12 @@ Public Class AdlibAdapter ' Based on fake86's implementation
194194
adlibEnv(port Mod 9) = 0.0025
195195
End If
196196

197-
adlibChan(port Mod 9).Frequency = adlibRegMem(&HA0 + port) Or ((adlibRegMem(&HB0 + port) And 3) << 8)
198-
adlibChan(port Mod 9).ConvFreq = adlibChan(port Mod 9).Frequency * 0.7626459
199-
adlibChan(port Mod 9).KeyOn = ((adlibRegMem(&HB0 + port) >> 5) And 1) = 1
200-
adlibChan(port Mod 9).Octave = (adlibRegMem(&HB0 + port) >> 2) And 7
197+
SyncLock adlibChan
198+
adlibChan(port Mod 9).Frequency = adlibRegMem(&HA0 + port) Or ((adlibRegMem(&HB0 + port) And 3) << 8)
199+
adlibChan(port Mod 9).ConvFreq = adlibChan(port Mod 9).Frequency * 0.7626459
200+
adlibChan(port Mod 9).KeyOn = ((adlibRegMem(&HB0 + port) >> 5) And 1) = 1
201+
adlibChan(port Mod 9).Octave = (adlibRegMem(&HB0 + port) >> 2) And 7
202+
End SyncLock
201203
ElseIf port >= &HE0 And port <= &HF5 Then ' Waveform select
202204
adlibChan((port And 15) Mod 9).WaveformSelect = value And 3
203205
End If
@@ -223,7 +225,7 @@ Public Class AdlibAdapter ' Based on fake86's implementation
223225
End Function
224226

225227
Private Function AdlibSample(channel As Byte) As Int32
226-
If AdlibFrequency(channel) = 0 OrElse (adlibPrecussion AndAlso channel >= 6 AndAlso channel <= 8) Then Return 0
228+
If adlibPrecussion AndAlso channel >= 6 AndAlso channel <= 8 Then Return 0
227229

228230
Dim fullStep As UInt32 = SampleRate \ AdlibFrequency(channel)
229231
Dim idx As Byte = (adlibStep(channel) / (fullStep / 256.0)) Mod 255
@@ -239,9 +241,11 @@ Public Class AdlibAdapter ' Based on fake86's implementation
239241

240242
Private Function AdlibGenerateSample() As Int16
241243
Dim adlibAccumulator As Int16 = 0
242-
For currentChannel As Byte = 0 To 9 - 1
243-
If AdlibFrequency(currentChannel) <> 0 Then adlibAccumulator += AdlibSample(currentChannel)
244-
Next
244+
SyncLock adlibChan
245+
For currentChannel As Byte = 0 To 9 - 1
246+
If AdlibFrequency(currentChannel) <> 0 Then adlibAccumulator += AdlibSample(currentChannel)
247+
Next
248+
End SyncLock
245249
Return adlibAccumulator
246250
End Function
247251

x8086NetEmu/Adapters/Video/CGA/CGAAdapter.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Public MustInherit Class CGAAdapter
66
Public Const VERTSYNC As Double = 60.0
77
Public Const HORIZSYNC As Double = VERTSYNC * 262.5
88

9-
Protected ht As Long = Scheduler.CLOCKRATE \ HORIZSYNC
10-
Protected vt As Long = (Scheduler.CLOCKRATE \ HORIZSYNC) * (HORIZSYNC \ VERTSYNC)
9+
Protected ht As Long = Scheduler.BASECLOCK \ HORIZSYNC
10+
Protected vt As Long = (Scheduler.BASECLOCK \ HORIZSYNC) * (HORIZSYNC \ VERTSYNC)
1111

1212
Public Enum VideoModes
1313
Mode0_Text_BW_40x25 = &H4

x8086NetEmu/Adapters/Video/VGA/VGAAdapter.vb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@
281281
'Private port3DA As UInt32
282282
Private Const planeSize As UInt32 = &H10000
283283
Private lastScanLineTick As Long
284-
Private ReadOnly scanLineTiming As Long = (Scheduler.CLOCKRATE / X8086.KHz) / 31500
284+
Private ReadOnly scanLineTiming As Long = (Scheduler.BASECLOCK / X8086.KHz) / 31500
285285
Private curScanLine As Long
286286
Private cursorPosition As UInt32
287287
Private blinkCounter As Integer

x8086NetEmu/Chipset/DMA8237.vb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@
263263
' DMA verify
264264
curcount -= maxlen
265265
curaddr = (curaddr + maxlen * addrstep) And &HFFFF
266-
transferTime += 3 * maxlen * Scheduler.CLOCKRATE / cpu.Clock
266+
transferTime += 3 * maxlen * Scheduler.BASECLOCK / cpu.Clock
267267
Case &H4
268268
' DMA write
269269
While (maxlen > 0) AndAlso (Not chan.externalEop) AndAlso (blockmode OrElse chan.pendingRequest)
@@ -274,7 +274,7 @@
274274
maxlen -= 1
275275
curcount -= 1
276276
curaddr = (curaddr + addrstep) And &HFFFF
277-
transferTime += 3 * Scheduler.CLOCKRATE / cpu.Clock
277+
transferTime += 3 * Scheduler.BASECLOCK / cpu.Clock
278278
End While
279279
Case &H8
280280
' DMA read
@@ -286,7 +286,7 @@
286286
maxlen -= 1
287287
curcount -= 1
288288
curaddr = (curaddr + addrstep) And &HFFFF
289-
transferTime += 3 * Scheduler.CLOCKRATE / cpu.Clock
289+
transferTime += 3 * Scheduler.BASECLOCK / cpu.Clock
290290
End While
291291
End Select
292292

x8086NetEmu/Chipset/PIT8254.vb

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
Update()
9595
' fill status latch register:
9696
' bit7 = output
97-
' bit6 = nullcount
97+
' bit6 = null count
9898
' bit4-5 = rwMode
9999
' bit1-3 = countMode
100100
' bit0 = bcdMode
@@ -650,12 +650,10 @@
650650
End Property
651651

652652
Private Sub UpdateCh0()
653-
' State of channel 0 may have changed;
654-
'' run the IRQ task immediately to take this into account
655-
If irq IsNot Nothing Then
656-
task.Cancel()
657-
task.Start()
658-
End If
653+
' State of channel 0 may have changed
654+
' Run the IRQ task immediately to take this into account
655+
task.Cancel()
656+
task.Start()
659657
End Sub
660658

661659
Private Sub UpdateCh1()
@@ -665,7 +663,7 @@
665663

666664
Private Sub UpdateCh2(v As Integer)
667665
'If cpu.PPI IsNot Nothing Then
668-
' If cpu.Model = x8086.Models.PCE_IBMPC_5150 Then
666+
' If cpu.Model = X8086.Models.IBMPC_5150 Then
669667
' If v <> 0 Then
670668
' cpu.PPI.PortC(0) = cpu.PPI.PortC(0) Or &H20
671669
' cpu.PPI.PortC(1) = cpu.PPI.PortC(1) Or &H20
@@ -692,13 +690,13 @@
692690
End Sub
693691

694692
Public Shared Function TimeToClocks(t As Long) As Long
695-
Return (t \ Scheduler.CLOCKRATE) * COUNTRATE +
696-
((t Mod Scheduler.CLOCKRATE) * COUNTRATE) \ Scheduler.CLOCKRATE
693+
Return (t \ Scheduler.BASECLOCK) * COUNTRATE +
694+
((t Mod Scheduler.BASECLOCK) * COUNTRATE) \ Scheduler.BASECLOCK
697695
End Function
698696

699697
Public Shared Function ClocksToTime(c As Long) As Long
700-
Return (c \ COUNTRATE) * Scheduler.CLOCKRATE +
701-
((c Mod COUNTRATE) * Scheduler.CLOCKRATE + COUNTRATE - 1) \ COUNTRATE
698+
Return (c \ COUNTRATE) * Scheduler.BASECLOCK +
699+
((c Mod COUNTRATE) * Scheduler.BASECLOCK + COUNTRATE - 1) \ COUNTRATE
702700
End Function
703701

704702
Public Property Speaker As SpeakerAdpater
@@ -722,15 +720,15 @@
722720
End Get
723721
End Property
724722

725-
Private lastValue As Boolean = False
723+
Private lastChan0 As Boolean = False
726724
' Scheduled task to drive IRQ 0 based on counter 0 output signal
727725
Public Overrides Sub Run()
728726
currentTime = cpu.Sched.CurrentTime
729-
' set IRQ 0 signal equal to counter 0 output
727+
' Set IRQ 0 signal equal to counter 0 output
730728
Dim s As Boolean = mChannels(0).GetOutput()
731-
If s <> lastValue Then
729+
If s <> lastChan0 Then
732730
irq.Raise(s)
733-
lastValue = s
731+
lastChan0 = s
734732
End If
735733

736734
' reschedule task for next output change

x8086NetEmu/Helpers/Helpers.vb

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,10 @@
182182
End Function
183183

184184
Private Sub SendToPort(portAddress As UInt32, value As UInt32)
185+
FlushCycles()
186+
185187
If portsCache.ContainsKey(portAddress) Then
186188
portsCache(portAddress).Out(portAddress, value)
187-
'FlushCycles()
188189
'X8086.Notify(String.Format("Write {0} to Port {1} on Adapter '{2}'", value.ToString("X2"), portAddress.ToString("X4"), portsCache(portAddress).Name), NotificationReasons.Info)
189190
Exit Sub
190191
Else
@@ -194,7 +195,6 @@
194195
'X8086.Notify(String.Format("Write {0} to Port {1} on Adapter '{2}'", value.ToString("X2"), portAddress.ToString("X4"), p.Name), NotificationReasons.Info)
195196

196197
portsCache.Add(portAddress, p)
197-
'FlushCycles()
198198
Exit Sub
199199
End If
200200
Next
@@ -205,7 +205,6 @@
205205
'X8086.Notify(String.Format("Write {0} to Port {1} on Adapter '{2}'", value.ToString("X2"), portAddress.ToString("X4"), a.Name), NotificationReasons.Info)
206206

207207
portsCache.Add(portAddress, a)
208-
'FlushCycles()
209208
Exit Sub
210209
End If
211210
Next
@@ -215,8 +214,9 @@
215214
End Sub
216215

217216
Private Function ReceiveFromPort(portAddress As UInt32) As UInt32
217+
FlushCycles()
218+
218219
If portsCache.ContainsKey(portAddress) Then
219-
FlushCycles()
220220
'X8086.Notify(String.Format("Read From Port {0} on Adapter '{1}'", portAddress.ToString("X4"), portsCache(portAddress).Name), NotificationReasons.Info)
221221
Return portsCache(portAddress).In(portAddress)
222222
Else
@@ -225,7 +225,6 @@
225225
'X8086.Notify(String.Format("Read From Port {0} on Adapter '{1}'", portAddress.ToString("X4"), p.Name), NotificationReasons.Info)
226226

227227
portsCache.Add(portAddress, p)
228-
FlushCycles()
229228
Return p.In(portAddress)
230229
End If
231230
Next
@@ -235,7 +234,6 @@
235234
'X8086.Notify(String.Format("Read From Port {0} on Adapter '{1}'", portAddress.ToString("X4"), a.Name), NotificationReasons.Info)
236235

237236
portsCache.Add(portAddress, a)
238-
FlushCycles()
239237
Return a.In(portAddress)
240238
End If
241239
Next

x8086NetEmu/Helpers/Misc/Scheduler.vb

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ Public Class Scheduler
88
Private Const NOTASK As Long = Long.MaxValue
99
Private Const STOPPING As Long = Long.MinValue
1010

11-
Public Const BASECLOCK = 1.19318 * X8086.GHz
12-
1311
' Number of scheduler time units per simulated second (~1.0 GHz)
14-
Private Shared mCLOCKRATE As Long = BASECLOCK
12+
Public Const BASECLOCK = 1.19318 * X8086.GHz
1513

1614
' Current simulation time in scheduler time units (ns)
1715
Private mCurrentTime As Long
@@ -111,7 +109,8 @@ Public Class Scheduler
111109
pq = New PriorityQueue()
112110
pendingInput = New ArrayList()
113111

114-
CLOCKRATE = BASECLOCK
112+
syncQuantum = BASECLOCK / 20
113+
syncSimTimePerWallMs = BASECLOCK / 1000
115114
End Sub
116115

117116
Public ReadOnly Property CurrentTime As Long
@@ -126,29 +125,6 @@ Public Class Scheduler
126125
End Get
127126
End Property
128127

129-
Public Shared Property CLOCKRATE
130-
Get
131-
Return mCLOCKRATE
132-
End Get
133-
Set(value)
134-
mCLOCKRATE = value
135-
syncQuantum = mCLOCKRATE / 20
136-
syncSimTimePerWallMs = mCLOCKRATE / 1000
137-
End Set
138-
End Property
139-
140-
'Public Sub SetInputHandler(inputHandler As KeyboardAdapter)
141-
' Me.inputHandler = inputHandler
142-
'End Sub
143-
144-
' Set simulation synchronization parameters.
145-
' @param enable Enables slowing the simulation to keep it
146-
' in sync with real time.
147-
' @param quantum Determines how often the synchronization is checked
148-
' (in simulated nanoseconds).
149-
' @param simTimePerWallMs Determines the speed of the simulation
150-
' (in simulated nanoseconds per real millisecond).
151-
'
152128
Public Sub SetSynchronization(enabled As Boolean, quantum As Long, simTimePerWallMs As Long, simulationMultiplier As Double)
153129
#If DEBUG Then
154130
If enabled And quantum < 1 Then Throw New ArgumentException("Invalid value for quantum")
@@ -229,7 +205,7 @@ Public Class Scheduler
229205
End Sub
230206

231207
Public Function GetTimeToNextEvent() As Long
232-
If nextTime = STOPPING OrElse Not (pendingInput.Count = 0) Then
208+
If nextTime = STOPPING OrElse pendingInput.Count <> 0 Then
233209
Return 0
234210
ElseIf syncScheduler AndAlso (nextTime > mCurrentTime + syncQuantum) Then
235211
Return syncQuantum
@@ -300,7 +276,7 @@ Public Class Scheduler
300276
Dim wallTime As Long = CurrentTimeMillis()
301277
Dim wallDelta As Long = wallTime - syncWallTimeMillis
302278
syncWallTimeMillis = wallTime
303-
If (wallDelta < 0) Then wallDelta = 0 ' some clown has set the system clock back
279+
If wallDelta < 0 Then wallDelta = 0 ' some clown has set the system clock back
304280
syncTimeSaldo -= wallDelta * syncSimTimePerWallMs
305281
If syncTimeSaldo < 0 Then syncTimeSaldo = 0
306282
If syncTimeSaldo > 2 * syncQuantum Then
@@ -353,7 +329,7 @@ Public Class Scheduler
353329

354330
SyncLock tsk
355331
If (tsk.NextTime = Task.NOSCHED) OrElse (tsk.NextTime > mCurrentTime) Then
356-
' Cancelled or rescheduled
332+
' Canceled or rescheduled
357333
tsk = Nothing
358334
Else
359335
' Task is ok to run
@@ -380,14 +356,14 @@ Public Class Scheduler
380356
syncWallTimeMillis = CurrentTimeMillis()
381357
syncTimeSaldo = 0
382358

383-
loopThread = New Thread(AddressOf Run)
384-
loopThread.Start()
359+
Tasks.Task.Run(AddressOf Run)
385360
End Sub
386361

387362
Private Sub Run()
388363
Dim cleanInputBuf As New ArrayList()
389364
Dim inputBuf As New ArrayList()
390365
Dim tsk As Task = Nothing
366+
Dim evt As ExternalInputEvent
391367

392368
While True
393369
' Detect the end of the simulation run
@@ -403,10 +379,7 @@ Public Class Scheduler
403379
ElseIf nextTime <= mCurrentTime Then
404380
' Fetch the next pending task
405381
tsk = NextTask()
406-
If tsk Is Nothing Then
407-
' This task was canceled, go round again
408-
Continue While
409-
End If
382+
If tsk Is Nothing Then Continue While ' This task was canceled, go round again
410383
inputBuf.Clear()
411384
Else
412385
tsk = Nothing
@@ -415,10 +388,11 @@ Public Class Scheduler
415388
If inputBuf.Count > 0 Then
416389
' Process pending input events
417390
For i As Integer = 0 To inputBuf.Count - 1
418-
Dim evt As ExternalInputEvent = CType(inputBuf.Item(i), ExternalInputEvent)
391+
evt = CType(inputBuf.Item(i), ExternalInputEvent)
419392
evt.TimeStamp = mCurrentTime
420393
' Tasks.Task.Run(Sub() evt.Handler.HandleInput(evt)) ' <- This freezes Windows 10!!!!
421-
evt.Handler.HandleInput(evt)
394+
Tasks.Task.Run(Sub() evt.Handler.HandleInput(evt))
395+
'evt.Handler.HandleInput(evt)
422396
Next
423397
inputBuf.Clear()
424398
cleanInputBuf = inputBuf
@@ -436,10 +410,7 @@ Public Class Scheduler
436410
ex.Message)
437411
End Try
438412

439-
If mCPU.IsHalted() Then
440-
' The CPU is halted, skip immediately to the next event
441-
SkipToNextEvent()
442-
End If
413+
If mCPU.IsHalted() Then SkipToNextEvent() ' The CPU is halted, skip immediately to the next event
443414
End If
444415
End While
445416
End Sub

x8086NetEmu/My Project/AssemblyInfo.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
3131
' by using the '*' as shown below:
3232
' <Assembly: AssemblyVersion("1.0.*")>
3333

34-
<Assembly: AssemblyVersion("2018.8.27.4419")>
35-
<Assembly: AssemblyFileVersion("2018.8.27.4412")>
34+
<Assembly: AssemblyVersion("2018.8.27.4505")>
35+
<Assembly: AssemblyFileVersion("2018.8.27.4498")>

0 commit comments

Comments
 (0)