Changeset 145 for MicroThreading/UMicroThreading.pas
- Timestamp:
- Jan 25, 2011, 8:51:57 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/UMicroThreading.pas
r144 r145 96 96 FStackPointer: Pointer; 97 97 FBasePointer: Pointer; 98 FSelected: TMicroThread;99 98 FExecuteCount: Integer; 100 99 FExecutedCount: Integer; … … 105 104 Scheduler: TMicroThreadScheduler; 106 105 CurrentMicroThread: TMicroThread; 107 procedure Yield (MicroThread: TMicroThread);106 procedure Yield; 108 107 constructor Create; 109 108 destructor Destroy; override; … … 154 153 StaticMicroThread: TMicroThread; 155 154 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 155 function GetMicroThreadId: Integer; 156 var 157 I: Integer; 158 CurrentStack: Pointer; 159 begin 160 asm 161 mov CurrentStack, sp 162 end; 163 with MainScheduler do begin 164 try 165 Lock.Acquire; 166 I := 0; 167 while (I < MicroThreads.Count) and 168 not ((CurrentStack >= TMicroThread(MicroThreads[I]).FStack) and 169 (CurrentStack <= (TMicroThread(MicroThreads[I]).FStack + 170 TMicroThread(MicroThreads[I]).FStackSize))) do Inc(I); 171 if I < MicroThreads.Count then begin 172 Result := TMicroThread(MicroThreads[I]).Id; 173 end else Result := -1; 174 finally 175 Lock.Release; 176 end; 177 end; 178 end; 180 179 181 180 { TMicroThreadManager } … … 187 186 FExecuteCount := Count; 188 187 FExecutedCount := 0; 189 Yield (nil);188 Yield; 190 189 Result := FExecutedCount; 191 190 end; 192 191 193 procedure TMicroThreadManager.Yield (MicroThread: TMicroThread);192 procedure TMicroThreadManager.Yield; 194 193 var 195 194 I: Integer; … … 197 196 begin 198 197 Time := Scheduler.GetNow; 199 if Assigned( MicroThread) then begin200 MicroThread.Manager := nil;201 MicroThread.FExecutionEndTime := Time;202 MicroThread.FExecutionTime := MicroThread.FExecutionTime +203 (MicroThread.FExecutionEndTime - MicroThread.FExecutionStartTime);204 if MicroThread.State = tsRunning then205 MicroThread.State := tsWaiting;198 if Assigned(CurrentMicroThread) then begin 199 CurrentMicroThread.FExecutionEndTime := Time; 200 CurrentMicroThread.FExecutionTime := CurrentMicroThread.FExecutionTime + 201 (CurrentMicroThread.FExecutionEndTime - CurrentMicroThread.FExecutionStartTime); 202 if CurrentMicroThread.State = tsRunning then 203 CurrentMicroThread.State := tsWaiting; 204 StaticMicroThread := CurrentMicroThread; 206 205 asm 207 206 // Store microthread stack 208 mov eax, MicroThread207 mov eax, StaticMicroThread 209 208 mov edx, esp 210 209 mov [eax].TMicroThread.FStackPointer, edx … … 212 211 mov [eax].TMicroThread.FBasePointer, edx 213 212 end; 214 StaticManager := MicroThread.Manager;213 StaticManager := CurrentMicroThread.Manager; 215 214 asm 216 215 // Restore scheduler stack … … 221 220 mov ebp, edx 222 221 end; 222 CurrentMicroThread.Manager := nil; 223 223 CurrentMicroThread := nil; 224 224 end; 225 225 226 FSelected := Scheduler.GetNextMicroThread;227 228 if Assigned( FSelected) and (FExecutedCount < FExecuteCount) then begin229 FSelected.Manager := Self;226 CurrentMicroThread := Scheduler.GetNextMicroThread; 227 228 if Assigned(CurrentMicroThread) and (FExecutedCount < FExecuteCount) then begin 229 CurrentMicroThread.Manager := Self; 230 230 Inc(FExecutedCount); 231 CurrentMicroThread := FSelected;232 231 asm 233 232 // Store scheduler stack … … 238 237 mov [eax].TMicroThreadManager.FBasePointer, edx 239 238 end; 240 if not FSelected.FExecuted then begin241 FSelected.FExecuted := True;242 FSelected.State := tsRunning;243 FSelected.FExecutionStartTime := Time;244 FTempPointer := FSelected.FStackPointer;239 if not CurrentMicroThread.FExecuted then begin 240 CurrentMicroThread.FExecuted := True; 241 CurrentMicroThread.State := tsRunning; 242 CurrentMicroThread.FExecutionStartTime := Time; 243 StaticMicroThread := CurrentMicroThread; 245 244 asm 246 245 // Restore microthread stack 247 mov eax, S elf248 mov edx, [eax].TMicroThread Manager.FTempPointer246 mov eax, StaticMicroThread 247 mov edx, [eax].TMicroThread.FStackPointer 249 248 mov esp, edx 250 end; 251 StaticMicroThread := FSelected; // BP will be change and Self pointer will be invalid 252 FTempPointer := FSelected.FBasePointer; 253 asm 254 mov eax, Self 255 mov edx, [eax].TMicroThreadManager.FTempPointer 249 mov edx, [eax].TMicroThread.FBasePointer 256 250 mov ebp, edx 257 251 end; … … 267 261 mov ebp, edx 268 262 end; 269 FSelected.Manager := nil; 270 FSelected.FExecutionEndTime := Time; 271 FSelected.FExecutionTime := FSelected.FExecutionTime + 272 (FSelected.FExecutionEndTime - FSelected.FExecutionStartTime); 273 FSelected.FFinished := True; 274 if FSelected.FFreeOnTerminate then begin 275 FSelected.Free; 276 end;; 263 CurrentMicroThread.Manager := nil; 264 CurrentMicroThread.FExecutionEndTime := Time; 265 CurrentMicroThread.FExecutionTime := CurrentMicroThread.FExecutionTime + 266 (CurrentMicroThread.FExecutionEndTime - CurrentMicroThread.FExecutionStartTime); 267 CurrentMicroThread.FFinished := True; 268 if CurrentMicroThread.FFreeOnTerminate then begin 269 CurrentMicroThread.Free; 270 end; 271 CurrentMicroThread := nil; 277 272 end else 278 if FSelected.State = tsWaiting then begin273 if CurrentMicroThread.State = tsWaiting then begin 279 274 // Execute selected thread 280 FSelected.State := tsRunning;281 FSelected.FExecutionStartTime := Time;282 FTempPointer := FSelected.FStackPointer;275 CurrentMicroThread.State := tsRunning; 276 CurrentMicroThread.FExecutionStartTime := Time; 277 FTempPointer := CurrentMicroThread.FStackPointer; 283 278 asm 284 279 // Restore microthread stack … … 287 282 mov esp, edx 288 283 end; 289 FTempPointer := FSelected.FBasePointer;284 FTempPointer := CurrentMicroThread.FBasePointer; 290 285 asm 291 286 mov eax, Self … … 294 289 end; 295 290 end; 291 end else begin 292 CurrentMicroThread := nil; 296 293 end; 297 294 end; … … 299 296 constructor TMicroThreadManager.Create; 300 297 begin 301 298 CurrentMicroThread := nil; 302 299 end; 303 300 … … 343 340 procedure TMicroThread.Yield; 344 341 begin 345 Manager.Yield (Self);342 Manager.Yield; 346 343 end; 347 344 … … 430 427 fpgettimeofday(@t, nil); 431 428 // Build a 64 bit microsecond tick from the seconds and microsecond longints 432 Result := (Int64(t.tv_sec) * 1000000) + t.tv_usec;429 Result := t.tv_sec + t.tv_usec / 1000000; 433 430 {$ENDIF} 434 431
Note:
See TracChangeset
for help on using the changeset viewer.