Changeset 134 for Microthreading/umicrothreading.pas
- Timestamp:
- Jan 23, 2011, 7:25:13 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Microthreading/umicrothreading.pas
r133 r134 30 30 FStack: Pointer; 31 31 FStackSize: Integer; 32 FInstructionPointer: Pointer;33 32 FExecutionStartTime: TDateTime; 34 33 FExecutionEndTime: TDateTime; 34 FStackPointer: Pointer; 35 FBasePointer: Pointer; 35 36 FWakeupTime: TDateTime; 36 procedure Finish;37 procedure SaveContext;38 procedure RestoreContext;39 procedure Init;40 37 public 41 FStackPointer: Pointer;42 38 Id: Integer; 43 39 Name: string; … … 65 61 RoundRobinIndex: Integer; 66 62 LastId: Integer; 67 FStackPointer: Pointer; 63 FMainStackPointer: Pointer; 64 FMainBasePointer: Pointer; 65 FSelected: TMicroThread; 66 FTempPointer: Pointer; 68 67 procedure Yield(MicroThread: TMicroThread); 69 68 public … … 94 93 FStackSize := $10000; 95 94 FStack := GetMem(FStackSize); 96 FStackPointer := FStack + FStackSize; 95 FBasePointer := FStack + FStackSize; 96 FStackPointer := FBasePointer - 20; 97 97 end; 98 98 … … 101 101 FreeMem(FStack); 102 102 inherited Destroy; 103 end;104 105 procedure TMicroThread.SaveContext; assembler; nostackframe;106 asm107 mov eax, Self108 mov edx, esp109 mov [eax].FStackPointer, edx110 pop edx111 mov [eax].FInstructionPointer, edx112 end;113 114 procedure TMicroThread.RestoreContext; assembler; nostackframe;115 asm116 mov eax, Self117 mov edx, [eax].FStackPointer118 mov esp, edx119 mov edx, [eax].FInstructionPointer120 push edx121 ret122 end;123 124 procedure TMicroThread.Init;125 var126 FProc: TCallerAddr;127 begin128 FProc.A := Method;129 FInstructionPointer := FProc.B;130 end;131 132 procedure TMicroThread.Finish;133 begin134 // Microthread is finished, remove it from queue135 try136 Scheduler.Lock.Acquire;137 Scheduler.MicroThreads.Delete(Scheduler.MicroThreads.IndexOf(Self));138 finally139 Scheduler.Lock.Release;140 end;141 103 end; 142 104 … … 154 116 Inc(LastId); 155 117 NewMicroThread.Id := LastId; 156 NewMicroThread.Init;157 118 MicroThreads.Add(NewMicroThread); 158 119 end; … … 175 136 procedure TMicroThreadScheduler.Start; 176 137 begin 138 RoundRobinIndex := -1; 177 139 Yield(nil); 178 140 end; 141 142 var 143 StaticMicroThread: TMicroThread; 144 StaticScheduler: TMicroThreadScheduler; 179 145 180 146 procedure TMicroThreadScheduler.Yield(MicroThread: TMicroThread); … … 184 150 if Assigned(MicroThread) then begin 185 151 MicroThread.FExecutionStartTime := Now; 186 MicroThread.SaveContext;187 152 MicroThread.State := tsSleeping; 188 153 asm 154 // Store microthread stack 155 mov eax, MicroThread 156 mov edx, esp 157 mov [eax].TMicroThread.FStackPointer, edx 158 mov edx, ebp 159 mov [eax].TMicroThread.FBasePointer, edx 160 end; 161 StaticScheduler := MicroThread.Scheduler; 162 asm 189 163 // Restore scheduler stack 190 mov eax, S elf191 mov edx, [eax]. FStackPointer164 mov eax, StaticScheduler // Self is invalid before BP restore 165 mov edx, [eax].TMicroThreadScheduler.FMainStackPointer 192 166 mov esp, edx 167 mov edx, [eax].TMicroThreadScheduler.FMainBasePointer 168 mov ebp, edx 193 169 end; 194 170 end; 195 171 196 172 // Try to find new microthread for execution 173 FSelected := nil; 197 174 try 198 175 Lock.Acquire; 199 176 I := 0; 200 while (I < MicroThreads.Count) and (TMicroThread(MicroThreads[I]).State <> tsReady) do 177 Inc(RoundRobinIndex); 178 if RoundRobinIndex >= MicroThreads.Count then 179 RoundRobinIndex := 0; 180 while (I < MicroThreads.Count) and (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsReady) and 181 (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsSleeping) do begin 201 182 Inc(I); 183 Inc(RoundRobinIndex); 184 if RoundRobinIndex >= MicroThreads.Count then 185 RoundRobinIndex := 0; 186 end; 202 187 if I < MicroThreads.Count then begin 203 MicroThread := TMicroThread(MicroThreads[I]);188 FSelected := TMicroThread(MicroThreads[RoundRobinIndex]); 204 189 end; 205 190 finally … … 207 192 end; 208 193 209 if Assigned( MicroThread) then begin194 if Assigned(FSelected) then begin 210 195 asm 211 196 // Store scheduler stack 212 197 mov eax, Self 213 198 mov edx, esp 214 mov [eax].FStackPointer, edx 215 end; 216 if MicroThread.State = tsReady then begin 217 MicroThread.State := tsRunning; 218 MicroThread.FExecutionStartTime := Now; 199 mov [eax].TMicroThreadScheduler.FMainStackPointer, edx 200 mov edx, ebp 201 mov [eax].TMicroThreadScheduler.FMainBasePointer, edx 202 end; 203 if FSelected.State = tsReady then begin 204 FSelected.State := tsRunning; 205 FSelected.FExecutionStartTime := Now; 206 FTempPointer := FSelected.FStackPointer; 219 207 asm 220 208 // Restore microthread stack 221 mov eax, MicroThread222 mov edx, [eax]. FStackPointer209 mov eax, Self 210 mov edx, [eax].TMicroThreadScheduler.FTempPointer 223 211 mov esp, edx 224 212 end; 225 MicroThread.Method(MicroThread); 213 StaticMicroThread := FSelected; // BP will be change and Self pointer will be invalid 214 FTempPointer := FSelected.FBasePointer; 215 asm 216 mov eax, Self 217 mov edx, [eax].TMicroThreadScheduler.FTempPointer 218 mov ebp, edx 219 end; 220 StaticMicroThread.Method(StaticMicroThread); 221 //FSelected.Method(FSelected); 222 StaticScheduler := StaticMicroThread.Scheduler; 226 223 asm 227 224 // Restore scheduler stack 228 mov eax, S elf229 mov edx, [eax]. FStackPointer225 mov eax, StaticScheduler // Self is invalid before BP restore 226 mov edx, [eax].TMicroThreadScheduler.FMainStackPointer 230 227 mov esp, edx 228 mov edx, [eax].TMicroThreadScheduler.FMainBasePointer 229 mov ebp, edx 230 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; 231 237 end; 232 238 end else 233 if MicroThread.State = tsSleeping then begin239 if FSelected.State = tsSleeping then begin 234 240 // Execute selected thread 235 MicroThread.State := tsRunning; 236 MicroThread.FExecutionStartTime := Now; 237 MicroThread.RestoreContext; 241 FSelected.State := tsRunning; 242 FSelected.FExecutionStartTime := Now; 243 FTempPointer := FSelected.FStackPointer; 244 asm 245 // Restore microthread stack 246 mov eax, Self 247 mov edx, [eax].TMicroThreadScheduler.FTempPointer 248 mov esp, edx 249 end; 250 FTempPointer := FSelected.FBasePointer; 251 asm 252 mov eax, Self 253 mov edx, [eax].TMicroThreadScheduler.FTempPointer 254 mov ebp, edx 255 end; 238 256 end; 239 257 end;
Note:
See TracChangeset
for help on using the changeset viewer.