Changeset 135
- Timestamp:
- Jan 23, 2011, 8:04:49 PM (14 years ago)
- Location:
- Microthreading
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
Microthreading/Demo/Demo.lpi
r134 r135 50 50 <TopLine Value="1"/> 51 51 <CursorPos X="1" Y="15"/> 52 <UsageCount Value="3 4"/>52 <UsageCount Value="35"/> 53 53 </Unit0> 54 54 <Unit1> … … 58 58 <ResourceBaseClass Value="Form"/> 59 59 <UnitName Value="UMainForm"/> 60 <IsVisibleTab Value="True"/>61 60 <EditorIndex Value="0"/> 62 61 <WindowIndex Value="0"/> 63 <TopLine Value=" 125"/>64 <CursorPos X=" 7" Y="149"/>65 <UsageCount Value="3 4"/>62 <TopLine Value="66"/> 63 <CursorPos X="1" Y="83"/> 64 <UsageCount Value="35"/> 66 65 <Loaded Value="True"/> 67 66 <LoadedDesigner Value="True"/> … … 70 69 <Filename Value="../umicrothreading.pas"/> 71 70 <UnitName Value="UMicroThreading"/> 71 <IsVisibleTab Value="True"/> 72 72 <EditorIndex Value="7"/> 73 73 <WindowIndex Value="0"/> 74 <TopLine Value=" 146"/>75 <CursorPos X=" 9" Y="155"/>76 <UsageCount Value="1 7"/>74 <TopLine Value="84"/> 75 <CursorPos X="14" Y="101"/> 76 <UsageCount Value="18"/> 77 77 <Loaded Value="True"/> 78 78 </Unit2> … … 124 124 <TopLine Value="56"/> 125 125 <CursorPos X="24" Y="77"/> 126 <UsageCount Value="1 7"/>126 <UsageCount Value="18"/> 127 127 <Loaded Value="True"/> 128 128 <DefaultSyntaxHighlighter Value="Delphi"/> … … 135 135 <TopLine Value="264"/> 136 136 <CursorPos X="37" Y="141"/> 137 <UsageCount Value="1 7"/>137 <UsageCount Value="18"/> 138 138 <Loaded Value="True"/> 139 139 <DefaultSyntaxHighlighter Value="Delphi"/> … … 160 160 <TopLine Value="1046"/> 161 161 <CursorPos X="34" Y="1053"/> 162 <UsageCount Value="1 7"/>162 <UsageCount Value="18"/> 163 163 <Loaded Value="True"/> 164 164 </Unit12> … … 183 183 <TopLine Value="2271"/> 184 184 <CursorPos X="4" Y="2274"/> 185 <UsageCount Value="1 1"/>185 <UsageCount Value="12"/> 186 186 <Loaded Value="True"/> 187 187 </Unit15> … … 193 193 <TopLine Value="290"/> 194 194 <CursorPos X="51" Y="287"/> 195 <UsageCount Value="1 7"/>195 <UsageCount Value="18"/> 196 196 <Loaded Value="True"/> 197 197 </Unit16> … … 230 230 <TopLine Value="8"/> 231 231 <CursorPos X="11" Y="25"/> 232 <UsageCount Value="1 1"/>232 <UsageCount Value="12"/> 233 233 <Loaded Value="True"/> 234 234 </Unit21> … … 237 237 <Position1> 238 238 <Filename Value="../umicrothreading.pas"/> 239 <Caret Line=" 250" Column="1" TopLine="222"/>239 <Caret Line="49" Column="59" TopLine="17"/> 240 240 </Position1> 241 241 <Position2> 242 <Filename Value=" ../umicrothreading.pas"/>243 <Caret Line=" 251" Column="1" TopLine="223"/>242 <Filename Value="umainform.pas"/> 243 <Caret Line="166" Column="53" TopLine="75"/> 244 244 </Position2> 245 245 <Position3> 246 <Filename Value=" ../umicrothreading.pas"/>247 <Caret Line=" 255" Column="1" TopLine="225"/>246 <Filename Value="umainform.pas"/> 247 <Caret Line="79" Column="1" TopLine="73"/> 248 248 </Position3> 249 249 <Position4> 250 250 <Filename Value="../umicrothreading.pas"/> 251 <Caret Line=" 82" Column="1" TopLine="65"/>251 <Caret Line="146" Column="1" TopLine="129"/> 252 252 </Position4> 253 253 <Position5> 254 <Filename Value=" umainform.pas"/>255 <Caret Line="1 50" Column="1" TopLine="125"/>254 <Filename Value="../umicrothreading.pas"/> 255 <Caret Line="147" Column="1" TopLine="129"/> 256 256 </Position5> 257 257 <Position6> 258 <Filename Value=" umainform.pas"/>259 <Caret Line="15 1" Column="1" TopLine="125"/>258 <Filename Value="../umicrothreading.pas"/> 259 <Caret Line="158" Column="1" TopLine="140"/> 260 260 </Position6> 261 261 <Position7> 262 262 <Filename Value="../umicrothreading.pas"/> 263 <Caret Line=" 240" Column="1" TopLine="223"/>263 <Caret Line="184" Column="1" TopLine="177"/> 264 264 </Position7> 265 265 <Position8> 266 266 <Filename Value="../umicrothreading.pas"/> 267 <Caret Line="1 63" Column="37" TopLine="137"/>267 <Caret Line="185" Column="1" TopLine="177"/> 268 268 </Position8> 269 269 <Position9> 270 270 <Filename Value="../umicrothreading.pas"/> 271 <Caret Line="1 55" Column="9" TopLine="137"/>271 <Caret Line="186" Column="1" TopLine="177"/> 272 272 </Position9> 273 273 <Position10> 274 274 <Filename Value="../umicrothreading.pas"/> 275 <Caret Line="1 62" Column="52" TopLine="137"/>275 <Caret Line="187" Column="1" TopLine="177"/> 276 276 </Position10> 277 277 <Position11> 278 278 <Filename Value="../umicrothreading.pas"/> 279 <Caret Line="1 61" Column="29" TopLine="145"/>279 <Caret Line="188" Column="1" TopLine="177"/> 280 280 </Position11> 281 281 <Position12> 282 282 <Filename Value="../umicrothreading.pas"/> 283 <Caret Line="1 55" Column="14" TopLine="145"/>283 <Caret Line="189" Column="1" TopLine="177"/> 284 284 </Position12> 285 285 <Position13> 286 286 <Filename Value="../umicrothreading.pas"/> 287 <Caret Line="1 43" Column="20" TopLine="135"/>287 <Caret Line="192" Column="1" TopLine="177"/> 288 288 </Position13> 289 289 <Position14> 290 290 <Filename Value="../umicrothreading.pas"/> 291 <Caret Line="2 16" Column="50" TopLine="196"/>291 <Caret Line="205" Column="1" TopLine="177"/> 292 292 </Position14> 293 293 <Position15> 294 294 <Filename Value="../umicrothreading.pas"/> 295 <Caret Line=" 158" Column="12" TopLine="144"/>295 <Caret Line="206" Column="1" TopLine="178"/> 296 296 </Position15> 297 297 <Position16> 298 298 <Filename Value="../umicrothreading.pas"/> 299 <Caret Line=" 164" Column="22" TopLine="144"/>299 <Caret Line="209" Column="1" TopLine="181"/> 300 300 </Position16> 301 301 <Position17> 302 302 <Filename Value="../umicrothreading.pas"/> 303 <Caret Line=" 157" Column="12" TopLine="144"/>303 <Caret Line="212" Column="1" TopLine="184"/> 304 304 </Position17> 305 305 <Position18> 306 306 <Filename Value="../umicrothreading.pas"/> 307 <Caret Line=" 164" Column="1" TopLine="144"/>307 <Caret Line="215" Column="1" TopLine="197"/> 308 308 </Position18> 309 309 <Position19> 310 310 <Filename Value="../umicrothreading.pas"/> 311 <Caret Line=" 165" Column="1" TopLine="144"/>311 <Caret Line="216" Column="1" TopLine="197"/> 312 312 </Position19> 313 313 <Position20> 314 314 <Filename Value="../umicrothreading.pas"/> 315 <Caret Line=" 166" Column="1" TopLine="144"/>315 <Caret Line="217" Column="1" TopLine="197"/> 316 316 </Position20> 317 317 <Position21> 318 318 <Filename Value="../umicrothreading.pas"/> 319 <Caret Line=" 167" Column="1" TopLine="144"/>319 <Caret Line="218" Column="1" TopLine="197"/> 320 320 </Position21> 321 321 <Position22> 322 322 <Filename Value="../umicrothreading.pas"/> 323 <Caret Line=" 168" Column="1" TopLine="144"/>323 <Caret Line="219" Column="1" TopLine="197"/> 324 324 </Position22> 325 325 <Position23> 326 326 <Filename Value="../umicrothreading.pas"/> 327 <Caret Line=" 173" Column="1" TopLine="145"/>327 <Caret Line="221" Column="1" TopLine="197"/> 328 328 </Position23> 329 329 <Position24> 330 330 <Filename Value="../umicrothreading.pas"/> 331 <Caret Line=" 174" Column="1" TopLine="146"/>331 <Caret Line="257" Column="35" TopLine="236"/> 332 332 </Position24> 333 333 <Position25> 334 334 <Filename Value="../umicrothreading.pas"/> 335 <Caret Line=" 161" Column="1" TopLine="146"/>335 <Caret Line="80" Column="38" TopLine="55"/> 336 336 </Position25> 337 337 <Position26> 338 <Filename Value=" ../umicrothreading.pas"/>339 <Caret Line=" 164" Column="1" TopLine="146"/>338 <Filename Value="umainform.pas"/> 339 <Caret Line="83" Column="31" TopLine="66"/> 340 340 </Position26> 341 341 <Position27> 342 342 <Filename Value="../umicrothreading.pas"/> 343 <Caret Line="1 65" Column="1" TopLine="146"/>343 <Caret Line="104" Column="1" TopLine="74"/> 344 344 </Position27> 345 345 <Position28> 346 346 <Filename Value="../umicrothreading.pas"/> 347 <Caret Line=" 166" Column="1" TopLine="146"/>347 <Caret Line="90" Column="28" TopLine="73"/> 348 348 </Position28> 349 349 <Position29> 350 350 <Filename Value="../umicrothreading.pas"/> 351 <Caret Line=" 167" Column="1" TopLine="146"/>351 <Caret Line="9" Column="70" TopLine="1"/> 352 352 </Position29> 353 353 <Position30> 354 354 <Filename Value="../umicrothreading.pas"/> 355 <Caret Line="1 68" Column="1" TopLine="146"/>355 <Caret Line="10" Column="27" TopLine="1"/> 356 356 </Position30> 357 357 </JumpHistory> … … 378 378 </CompilerOptions> 379 379 <Debugging> 380 <BreakPoints Count=" 6">380 <BreakPoints Count="5"> 381 381 <Item1> 382 382 <Source Value="../Coroutine.pas"/> … … 389 389 <Item3> 390 390 <Source Value="umainform.pas"/> 391 <Line Value="5 0"/>391 <Line Value="52"/> 392 392 </Item3> 393 393 <Item4> … … 399 399 <Line Value="145"/> 400 400 </Item5> 401 <Item6>402 <Source Value="umainform.pas"/>403 <Line Value="146"/>404 </Item6>405 401 </BreakPoints> 406 402 <Exceptions Count="3"> -
Microthreading/Demo/umainform.lfm
r133 r135 40 40 item 41 41 Caption = 'State' 42 Width = 165 42 Width = 60 43 end 44 item 45 Caption = 'Execution time' 46 Width = 105 43 47 end> 44 48 ReadOnly = True … … 81 85 TabOrder = 4 82 86 end 87 object Timer1: TTimer 88 Interval = 100 89 OnTimer = Timer1Timer 90 left = 399 91 top = 87 92 end 83 93 end -
Microthreading/Demo/umainform.pas
r134 r135 7 7 uses 8 8 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, 9 ComCtrls, UMicroThreading, Coroutine;9 ComCtrls, ExtCtrls, UMicroThreading, Coroutine, DateUtils; 10 10 11 11 type … … 26 26 ListView1: TListView; 27 27 Memo1: TMemo; 28 Timer1: TTimer; 28 29 procedure Button1Click(Sender: TObject); 29 30 procedure Button2Click(Sender: TObject); … … 31 32 procedure FormCreate(Sender: TObject); 32 33 procedure FormDestroy(Sender: TObject); 34 procedure Timer1Timer(Sender: TObject); 33 35 private 34 36 procedure Worker(MicroThread: TMicroThread); … … 65 67 begin 66 68 Scheduler := TMicroThreadScheduler.Create; 69 Scheduler.FreeMicroThreadOnFinish := False; 67 70 Test := TTest.Create; 68 71 end; … … 74 77 for I := 0 to 1 do 75 78 Scheduler.Add('Worker', Worker); 76 Scheduler.Start; 79 repeat 80 Scheduler.Start; 81 Application.ProcessMessages; 82 Sleep(1); 83 until Scheduler.MicroThreadCount = 0; 77 84 end; 78 85 … … 141 148 end; 142 149 150 procedure TForm1.Timer1Timer(Sender: TObject); 151 var 152 I: Integer; 153 NewItem: TListItem; 154 begin 155 try 156 ListView1.BeginUpdate; 157 ListView1.Clear; 158 Scheduler.Lock.Acquire; 159 for I := 0 to Scheduler.MicroThreads.Count - 1 do 160 with TMicroThread(Scheduler.MicroThreads[I]) do begin 161 NewItem := ListView1.Items.Add; 162 NewItem.Caption := IntToStr(Id); 163 NewItem.SubItems.Add(Name); 164 NewItem.SubItems.Add(''); 165 NewItem.SubItems.Add(IntToStr(Priority)); 166 NewItem.SubItems.Add(MicroThreadStateText[State]); 167 NewItem.SubItems.Add(FloatToStr(ExecutionTime)); 168 end; 169 finally 170 Scheduler.Lock.Release; 171 ListView1.EndUpdate; 172 end; 173 end; 174 143 175 procedure TForm1.Worker(MicroThread: TMicroThread); 144 176 var … … 149 181 for I := 0 to 10 do begin 150 182 Memo1.Lines.Add(InttoStr(Id) + ': ' + IntToStr(I)); 151 SysUtils.Sleep(10 * Id); 152 Yield; 183 Sleep(100 * Id * OneMillisecond); 153 184 end; 154 185 end; -
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.