Changeset 135 for Microthreading/umicrothreading.pas
- Timestamp:
- Jan 23, 2011, 8:04:49 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Microthreading/umicrothreading.pas
r134 r135 7 7 8 8 uses 9 Classes, SysUtils, Contnrs, SyncObjs; 9 Classes, SysUtils, Contnrs, SyncObjs, DateUtils, 10 BaseUnix, UnixUtil, Unix; 10 11 11 12 type … … 21 22 end; 22 23 23 TMicroThreadState = (tsReady, tsRunning, tsSleeping, tsBlocked, tsSuspended); 24 TMicroThreadState = (tsReady, tsRunning, tsWaiting, tsBlocked, tsSuspended, 25 tsSleeping, tsFinished); 24 26 25 27 { TMicroThread } … … 32 34 FExecutionStartTime: TDateTime; 33 35 FExecutionEndTime: TDateTime; 36 FExecutionTime: TDateTime; 34 37 FStackPointer: Pointer; 35 38 FBasePointer: Pointer; … … 46 49 destructor Destroy; override; 47 50 property Method: TStartEvent read FMethod write FMethod; 51 property ExecutionTime: TDateTime read FExecutionTime; 48 52 end; 49 53 … … 56 60 TMicroThreadScheduler = class 57 61 private 62 FFreeMicroThreadOnFinish: Boolean; 58 63 ThreadPool: TThreadPool; 59 MicroThreads: TObjectList; // TList<TMicroThread>60 Lock: TCriticalSection;61 64 RoundRobinIndex: Integer; 62 65 LastId: Integer; … … 65 68 FSelected: TMicroThread; 66 69 FTempPointer: Pointer; 70 function GetMicroThreadCount: Integer; 67 71 procedure Yield(MicroThread: TMicroThread); 68 72 public 73 MicroThreads: TObjectList; // TList<TMicroThread> 74 Lock: TCriticalSection; 69 75 function Add(Name: string; Method: TStartEvent): TMicroThread; 70 76 constructor Create; 71 77 destructor Destroy; override; 72 78 procedure Start; 73 end; 79 property MicroThreadCount: Integer read GetMicroThreadCount; 80 property FreeMicroThreadOnFinish: Boolean read FFreeMicroThreadOnFinish 81 write FFreeMicroThreadOnFinish; 82 end; 83 84 const 85 MicroThreadStateText: array[TMicroThreadState] of string = ('Ready', 'Running', 86 'Waiting', 'Blocked', 'Suspended', 'Sleeping', 'Finished'); 74 87 75 88 implementation 76 89 90 91 function SystemTicks: Int64; 92 {$IFDEF Windows} 93 begin 94 QueryPerformanceCounter(Result); 95 //Result := Int64(TimeStampToMSecs(DateTimeToTimeStamp(Now)) * 1000) // an alternative Win32 timebase 96 {$ELSE} 97 var t : timeval; 98 begin 99 fpgettimeofday(@t,nil); 100 // Build a 64 bit microsecond tick from the seconds and microsecond longints 101 Result := (Int64(t.tv_sec) * 1000000) + t.tv_usec; 102 {$ENDIF} 103 end; 104 105 77 106 { TMicroThread } 78 107 … … 84 113 procedure TMicroThread.Sleep(Duration: TDateTime); 85 114 begin 86 FWake upTime := Now + Duration;87 State := ts Blocked;115 FWakeUpTime := Now + Duration; 116 State := tsSleeping; 88 117 Yield; 89 118 end; … … 124 153 MicroThreads := TObjectList.Create; 125 154 ThreadPool := TThreadPool.Create; 155 FFreeMicroThreadOnFinish := True; 126 156 end; 127 157 … … 149 179 begin 150 180 if Assigned(MicroThread) then begin 151 MicroThread.FExecutionStartTime := Now; 152 MicroThread.State := tsSleeping; 181 MicroThread.FExecutionEndTime := Now; 182 MicroThread.FExecutionTime := MicroThread.FExecutionTime + 183 (MicroThread.FExecutionEndTime - MicroThread.FExecutionStartTime); 184 if MicroThread.State = tsRunning then 185 MicroThread.State := tsWaiting; 153 186 asm 154 187 // Store microthread stack … … 179 212 RoundRobinIndex := 0; 180 213 while (I < MicroThreads.Count) and (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsReady) and 181 (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsSleeping) do begin 182 Inc(I); 183 Inc(RoundRobinIndex); 184 if RoundRobinIndex >= MicroThreads.Count then 185 RoundRobinIndex := 0; 214 (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsWaiting) do begin 215 // WakeUp sleeping threads 216 if (TMicroThread(MicroThreads[RoundRobinIndex]).State = tsSleeping) and 217 (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < Now) then 218 TMicroThread(MicroThreads[RoundRobinIndex]).State := tsWaiting else 219 begin 220 // Go to next thread 221 Inc(I); 222 Inc(RoundRobinIndex); 223 if RoundRobinIndex >= MicroThreads.Count then 224 RoundRobinIndex := 0; 225 end; 186 226 end; 187 227 if I < MicroThreads.Count then begin … … 229 269 mov ebp, edx 230 270 end; 231 // Microthread is finished, remove it from queue 232 try 233 Lock.Acquire; 234 MicroThreads.Delete(MicroThreads.IndexOf(FSelected)); 235 finally 236 Lock.Release; 237 end; 271 if FFreeMicroThreadOnFinish then begin 272 // Microthread is finished, remove it from queue 273 try 274 Lock.Acquire; 275 MicroThreads.Delete(MicroThreads.IndexOf(FSelected)); 276 finally 277 Lock.Release; 278 end; 279 end else FSelected.State := tsFinished; 238 280 end else 239 if FSelected.State = ts Sleeping then begin281 if FSelected.State = tsWaiting then begin 240 282 // Execute selected thread 241 283 FSelected.State := tsRunning; … … 258 300 end; 259 301 302 function TMicroThreadScheduler.GetMicroThreadCount: Integer; 303 begin 304 try 305 Lock.Acquire; 306 Result := MicroThreads.Count; 307 finally 308 Lock.Release; 309 end; 310 end; 311 260 312 end. 261 313
Note:
See TracChangeset
for help on using the changeset viewer.