Changeset 140 for MicroThreading/UMicroThreading.pas
- Timestamp:
- Jan 24, 2011, 8:39:52 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/UMicroThreading.pas
r137 r140 1 1 unit UMicroThreading; 2 2 3 {$mode objfpc}{$H+}3 {$mode Delphi}{$H+} 4 4 {$asmmode intel} 5 5 … … 7 7 8 8 uses 9 Classes, SysUtils, Contnrs, SyncObjs, DateUtils, 10 BaseUnix, UnixUtil, Unix; 9 {$IFDEF Windows}Windows,{$ENDIF} 10 {$IFDEF Linux}BaseUnix, UnixUtil, Unix,{$ENDIF} 11 Classes, SysUtils, Contnrs, SyncObjs, DateUtils, Dialogs; 11 12 12 13 type … … 15 16 16 17 TStartEvent = procedure(MicroThread: TMicroThread) of object; 17 18 TCallerAddr = packed record19 case Boolean of20 True: (A: TStartEvent;);21 False: (B, C: Pointer;);22 end;23 18 24 19 TMicroThreadState = (tsReady, tsRunning, tsWaiting, tsBlocked, tsSuspended, … … 68 63 FSelected: TMicroThread; 69 64 FTempPointer: Pointer; 65 FFrequency: Int64; 66 FExecuteCount: Integer; 67 FExecutedCount: Integer; 70 68 function GetMicroThreadCount: Integer; 71 69 procedure Yield(MicroThread: TMicroThread); … … 73 71 MicroThreads: TObjectList; // TList<TMicroThread> 74 72 Lock: TCriticalSection; 73 function GetNow: TDateTime; 75 74 function Add(Name: string; Method: TStartEvent): TMicroThread; 76 75 constructor Create; 77 76 destructor Destroy; override; 78 procedure Start;77 function Execute(Count: Integer): Integer; 79 78 property MicroThreadCount: Integer read GetMicroThreadCount; 80 79 property FreeMicroThreadOnFinish: Boolean read FFreeMicroThreadOnFinish … … 89 88 90 89 91 function SystemTicks: Int64;92 {$IFDEF Windows}93 begin94 QueryPerformanceCounter(Result);95 //Result := Int64(TimeStampToMSecs(DateTimeToTimeStamp(Now)) * 1000) // an alternative Win32 timebase96 {$ELSE}97 var t : timeval;98 begin99 fpgettimeofday(@t,nil);100 // Build a 64 bit microsecond tick from the seconds and microsecond longints101 Result := (Int64(t.tv_sec) * 1000000) + t.tv_usec;102 {$ENDIF}103 end;104 105 106 90 { TMicroThread } 107 91 … … 113 97 procedure TMicroThread.Sleep(Duration: TDateTime); 114 98 begin 115 FWakeUpTime := Now + Duration;99 FWakeUpTime := Scheduler.GetNow + Duration; 116 100 State := tsSleeping; 117 101 Yield; … … 124 108 FBasePointer := FStack + FStackSize; 125 109 FStackPointer := FBasePointer - 20; 110 FExecutionTime := 0; 126 111 end; 127 112 … … 132 117 end; 133 118 119 134 120 { TMicroThreadScheduler } 121 122 function TMicroThreadScheduler.GetNow: TDateTime; 123 var 124 {$IFDEF Linux}T: TimeVal;{$ENDIF} 125 {$IFDEF Windows}TimerValue: Int64;{$ENDIF} 126 begin 127 {$IFDEF Windows} 128 QueryPerformanceCounter(TimerValue); 129 //Result := Int64(TimeStampToMSecs(DateTimeToTimeStamp(Now)) * 1000) // an alternative Win32 timebase 130 Result := TimerValue / FFrequency; 131 {$ENDIF} 132 {$IFDEF Linux} 133 fpgettimeofday(@t, nil); 134 // Build a 64 bit microsecond tick from the seconds and microsecond longints 135 Result := (Int64(t.tv_sec) * 1000000) + t.tv_usec; 136 {$ENDIF} 137 138 Result := (Trunc(Now / OneSecond) + Frac(Result)) * OneSecond; 139 end; 135 140 136 141 function TMicroThreadScheduler.Add(Name: string; Method: TStartEvent … … 154 159 ThreadPool := TThreadPool.Create; 155 160 FFreeMicroThreadOnFinish := True; 161 {$IFDEF Windows} 162 QueryPerformanceFrequency(FFrequency); 163 {$ENDIF} 164 RoundRobinIndex := -1; 156 165 end; 157 166 … … 164 173 end; 165 174 166 procedure TMicroThreadScheduler.Start; 167 begin 168 RoundRobinIndex := -1; 175 function TMicroThreadScheduler.Execute(Count: Integer): Integer; 176 begin 177 FExecuteCount := Count; 178 FExecutedCount := 0; 169 179 Yield(nil); 180 Result := FExecutedCount; 170 181 end; 171 182 … … 177 188 var 178 189 I: Integer; 179 begin 190 Time: TDateTime; 191 begin 192 Time := GetNow; 180 193 if Assigned(MicroThread) then begin 181 MicroThread.FExecutionEndTime := Now;194 MicroThread.FExecutionEndTime := Time; 182 195 MicroThread.FExecutionTime := MicroThread.FExecutionTime + 183 196 (MicroThread.FExecutionEndTime - MicroThread.FExecutionStartTime); … … 215 228 // WakeUp sleeping threads 216 229 if (TMicroThread(MicroThreads[RoundRobinIndex]).State = tsSleeping) and 217 (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < Now) then230 (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < Time) then 218 231 TMicroThread(MicroThreads[RoundRobinIndex]).State := tsWaiting else 219 232 begin … … 232 245 end; 233 246 234 if Assigned(FSelected) then begin 247 if Assigned(FSelected) and (FExecutedCount < FExecuteCount) then begin 248 Inc(FExecutedCount); 235 249 asm 236 250 // Store scheduler stack … … 243 257 if FSelected.State = tsReady then begin 244 258 FSelected.State := tsRunning; 245 FSelected.FExecutionStartTime := Now;259 FSelected.FExecutionStartTime := Time; 246 260 FTempPointer := FSelected.FStackPointer; 247 261 asm … … 269 283 mov ebp, edx 270 284 end; 285 FSelected.FExecutionEndTime := Time; 286 FSelected.FExecutionTime := FSelected.FExecutionTime + 287 (FSelected.FExecutionEndTime - FSelected.FExecutionStartTime); 271 288 if FFreeMicroThreadOnFinish then begin 272 289 // Microthread is finished, remove it from queue … … 282 299 // Execute selected thread 283 300 FSelected.State := tsRunning; 284 FSelected.FExecutionStartTime := Now;301 FSelected.FExecutionStartTime := Time; 285 302 FTempPointer := FSelected.FStackPointer; 286 303 asm
Note:
See TracChangeset
for help on using the changeset viewer.