Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

674 lines
14 KiB

  1. title SCHEDULE - task scheduler
  2. .xlist
  3. include kernel.inc
  4. include tdb.inc
  5. include eems.inc
  6. include newexe.inc
  7. .list
  8. if PMODE32
  9. .386
  10. endif
  11. externFP WriteOutProfiles
  12. externFP GlobalCompact
  13. externFP GetFreeSpace
  14. ;if KDEBUG
  15. ;externFP OutputDebugString
  16. ;endif
  17. DataBegin
  18. externB Kernel_InDOS
  19. externB Kernel_flags
  20. externB InScheduler
  21. externB fProfileDirty
  22. externB fProfileMaybeStale
  23. externB fPokeAtSegments
  24. externW WinFlags
  25. ;externW EMSCurPID
  26. ;externW cur_drive_owner
  27. externW curTDB
  28. externW Win_PDB
  29. externW LockTDB
  30. externW headTDB
  31. externW hShell
  32. externW pGlobalHeap
  33. externW hExeHead
  34. externW f8087
  35. externW
  36. if PMODE32
  37. externW PagingFlags
  38. externD pDisplayCritSec
  39. endif
  40. externD pIsUserIdle
  41. if KDEBUG
  42. externB fPreloadSeg
  43. endif
  44. staticW PokeCount,0
  45. DataEnd
  46. sBegin CODE
  47. assumes cs,CODE
  48. assumes ds,NOTHING
  49. assumes es,NOTHING
  50. externNP LoadSegment
  51. externNP DeleteTask
  52. externNP InsertTask
  53. if PMODE32
  54. externNP DiscardFreeBlocks
  55. externNP ShrinkHeap
  56. endif
  57. if SDEBUG
  58. externNP DebugSwitchOut
  59. externNP DebugSwitchIn
  60. endif
  61. ;-----------------------------------------------------------------------;
  62. ; Reschedule ;
  63. ; ;
  64. ; This routine does the task switching. ;
  65. ; ;
  66. ; Arguments: ;
  67. ; none ;
  68. ; Returns: ;
  69. ; nothing ;
  70. ; Error Returns: ;
  71. ; nothnig ;
  72. ; Registers Preserved: ;
  73. ; AX,BX,CX,DX,DI,SI,BP,DS,ES ;
  74. ; Registers Destroyed: ;
  75. ; none ;
  76. ; Calls: ;
  77. ; DeleteTask ;
  78. ; InsertTask ;
  79. ; SaveState ;
  80. ; ;
  81. ; History: ;
  82. ; ;
  83. ; Mon 07-Aug-1989 21:53:42 -by- David N. Weise [davidw] ;
  84. ; Removed the WinOldApp support and DEC rainbow support. ;
  85. ; ;
  86. ; Fri 07-Apr-1989 22:16:02 -by- David N. Weise [davidw] ;
  87. ; Added support for task ExeHeaders above The Line in Large ;
  88. ; Frame EMS. ;
  89. ; ;
  90. ; Sat Aug 15, 1987 11:41:35p -by- David N. Weise [davidw] ;
  91. ; Commented out the cli and sti around the swapping of states. ;
  92. ; Sweet Lord, what will this break? ;
  93. ; ;
  94. ; Fri Feb 06, 1987 00:09:20a -by- David N. Weise [davidw] ;
  95. ; Put in support for DirectedYield. ;
  96. ; ;
  97. ; Tue Feb 03, 1987 08:21:53p -by- David N. Weise [davidw] ;
  98. ; Got rid of going inside of DOS for InDOS and ErrorMode. Task ;
  99. ; switching should be much better under Windows386 now. ;
  100. ; ;
  101. ; Mon Sep 29, 1986 05:27:29p -by- Charles Whitmer [chuckwh] ;
  102. ; Made it recognize threads. It now does a fast context switch if ;
  103. ; just switching between two threads in the same process. ;
  104. ; ;
  105. ; Mon Sep 29, 1986 05:24:16p -by- Charles Whitmer [chuckwh] ;
  106. ; Documented it. ;
  107. ;-----------------------------------------------------------------------;
  108. assumes ds, nothing
  109. assumes es, nothing
  110. cProc Reschedule,<PUBLIC,FAR>
  111. cBegin nogen
  112. ; get all the registers up on the stack
  113. inc bp
  114. push bp
  115. mov bp,sp
  116. push ds
  117. push si
  118. push di
  119. push ax
  120. push cx
  121. push es
  122. push bx
  123. push dx
  124. public BootSchedule
  125. BootSchedule:
  126. call TaskSwitchProfileUpdate ;Update profile information
  127. public ExitSchedule
  128. ExitSchedule:
  129. ; see if we're supposed to do a directed yield
  130. SetKernelDS es
  131. mov cx,curTDB
  132. jcxz search_the_queue ; this happens first after boot time!
  133. mov ds,cx
  134. cmp ds:[TDB_sig],TDB_SIGNATURE
  135. jnz short search_the_queue ; task may have suicided
  136. xor cx,cx
  137. xchg ds:[TDB_Yield_to],cx
  138. jcxz search_the_queue ; nope
  139. mov ds,cx
  140. cmp ds:[TDB_nevents],0 ; anything for this guy?
  141. jnz found_one
  142. ; run down the task queue looking for someone with events
  143. search_the_queue:
  144. CheckKernelDS es
  145. mov ax,HeadTDB
  146. keep_searching:
  147. or ax,ax ; Anyone to schedule?
  148. jnz short try_this_one ; Yes, go do it
  149. ; if no one is dispatchable, do an idle interrupt
  150. if PMODE32
  151. xor PagingFlags, 4
  152. test PagingFlags, 4
  153. jnz short NoDiscarding ; Every other time through!
  154. test PagingFlags, 8 ; An app has exited?
  155. jz short NoShrink
  156. push es
  157. call ShrinkHeap
  158. pop es
  159. NoShrink:
  160. ;;; or PagingFlags, 2 ; Causes early exit from GlobalCompact
  161. ;;; mov ax, -1
  162. ;;; push es
  163. ;;; cCall GlobalCompact,<ax,ax>
  164. ;;; pop es
  165. ;;; and PagingFlags, not 2
  166. test byte ptr WinFlags[1], WF1_PAGING
  167. jz short NoDiscarding
  168. test PagingFlags, 1
  169. jz short NoDiscarding
  170. call DiscardFreeBlocks
  171. jmps search_the_queue
  172. NoDiscarding:
  173. endif
  174. mov ax, 1 ; Assume User is idle
  175. cmp word ptr pIsUserIdle[2], 0
  176. je short go_idle
  177. call pIsUserIdle
  178. SetKernelDS es
  179. go_idle:
  180. cmp fPokeAtSegments, 0 ; Disabled?
  181. je short @F ; yep, skip
  182. or ax, ax ; Only if USER is idle
  183. jz short @F
  184. inc PokeCount
  185. test PokeCount, 1Fh ; Only every 32 times through
  186. jnz short @F
  187. call PokeAtSegments
  188. jc search_the_queue
  189. @@:
  190. push ax ; Ralph's paranoia
  191. int 28h ; No, generate DOS idle int
  192. pop ax
  193. xor bx, bx
  194. or ax, ax
  195. jnz short tell_ralph
  196. or bl, 1
  197. tell_ralph:
  198. mov ax,1689h ; Do an idle to Win386.
  199. int 2fh
  200. jmp search_the_queue
  201. get_out_fast:
  202. jmp reschedule_done
  203. ; see if the given task has events
  204. try_this_one:
  205. mov ds,ax
  206. mov ax,ds:[TDB_next]
  207. cmp ds:[TDB_nevents],0 ; anything for this guy?
  208. jz keep_searching
  209. ; is this the guy we're already running?
  210. found_one:
  211. mov di,ds ; DI = handle of new task
  212. cmp di,curTDB
  213. jz short get_out_fast
  214. ; is there a locked task?
  215. mov cx,LockTDB ; are any tasks super priority?
  216. jcxz no_locked_task
  217. cmp cx,di ; are we it?
  218. jnz short get_out_fast ; No => don't switch
  219. no_locked_task:
  220. ; don't switch if in DOS or int 24 handler
  221. cmp Kernel_InDOS,0 ; if inside INT2[0,4] handler
  222. jnz keep_searching ; ...don't reschedule
  223. inc InScheduler ; set flag for INT 24...
  224. inc ds:[TDB_priority] ; lower task priority
  225. push es
  226. UnSetKernelDS es
  227. cCall DeleteTask,<ds> ; remove him from queue
  228. cCall InsertTask,<ds> ; put him back further down
  229. dec ds:[TDB_priority] ; restore former priority
  230. pop es
  231. ReSetKernelDS es
  232. ; Around saving state and restoring state go critical on memory
  233. ; heap access because of EMS.
  234. push es
  235. mov es,pGlobalHeap
  236. UnSetKernelDS es
  237. inc es:[gi_lrulock]
  238. pop es
  239. ReSetKernelDS es
  240. ; Signature is trashed when we suicide so we dont save state
  241. ; for the non-existant task.
  242. mov di,ds ; DI = destination task
  243. xor si,si ; SI is an argument to RestoreState
  244. mov es,curTDB ; ES = current TDB
  245. UnSetKernelDS es
  246. mov ax,es
  247. or ax,ax
  248. jz short dont_save_stack
  249. cmp es:[TDB_sig],TDB_SIGNATURE
  250. jnz short dont_save_stack
  251. mov si,es ; SI = current task
  252. ; save the present stack
  253. mov es:[TDB_taskSS],ss
  254. mov es:[TDB_taskSP],sp
  255. dont_save_stack:
  256. ; get onto a temporary stack while we switch the EEMS memory
  257. mov ax,es
  258. or ax,ax
  259. jz short dont_save_state
  260. cmp es:[TDB_sig],TDB_SIGNATURE
  261. jnz short dont_save_state
  262. cCall SaveState,<si>
  263. push ds
  264. mov ds,ax
  265. if SDEBUG
  266. call DebugSwitchOut
  267. endif
  268. pop ds
  269. dont_save_state:
  270. SetKernelDS es
  271. mov curTDB,di
  272. mov ax, ds:[TDB_PDB] ; Set our idea of the PDB
  273. mov Win_PDB, ax
  274. ;;;mov ax,ds:[TDB_EMSPID]
  275. ;;;mov EMSCurPID,ax
  276. cmp f8087, 0
  277. je short no_fldcw
  278. .8087
  279. fnclex
  280. fldcw ds:[TDB_FCW]
  281. no_fldcw:
  282. or Kernel_flags,kf_restore_CtrlC OR kf_restore_disk
  283. if SDEBUG
  284. call DebugSwitchIn
  285. endif
  286. fast_switch:
  287. mov cx,ds:[TDB_taskSS] ; Switch to new task stack.
  288. mov ax,ds:[TDB_taskSP]
  289. mov ss,cx
  290. mov sp,ax
  291. mov curTDB,di
  292. dec InScheduler ; reset flag for INT 24
  293. if PMODE32
  294. mov al,Kernel_Flags[2]
  295. and Kernel_Flags[2],NOT KF2_WIN386CRAZINESS
  296. ; Tell the display driver to speak its mind. added 20 feb 1990
  297. test al,KF2_WIN386CRAZINESS
  298. jz short @F
  299. xor ax,ax
  300. push es ; preserve es
  301. cCall pDisplayCritSec,<ax>
  302. pop es
  303. @@:
  304. endif
  305. ; Around saving state and restoring state go critical on memory
  306. ; arena access because of EMS.
  307. mov es,pGlobalHeap
  308. UnSetKernelDS es
  309. dec es:[gi_lrulock]
  310. ; pop the task's registers off the stack
  311. reschedule_done:
  312. pop dx
  313. pop bx
  314. pop es
  315. pop cx
  316. pop ax
  317. pop di
  318. pop si
  319. pop ds
  320. pop bp
  321. dec bp
  322. public dispatch
  323. dispatch:
  324. ret
  325. cEnd nogen
  326. ;-----------------------------------------------------------------------;
  327. ; LockCurrentTask ;
  328. ; ;
  329. ; Hack procedure to make the current task god if the passed boolean ;
  330. ; is true. ;
  331. ; If false, then demotes the current god to a mere mortal. Self ;
  332. ; inflicted by definition. ;
  333. ; ;
  334. ; DavidDS: Note, the USER function, LockMyTask should be called for ;
  335. ; Windows apps instead of this if you expect the input queue to work ;
  336. ; properly. ;
  337. ; ;
  338. ; Arguments: ;
  339. ; ParmW lock ; ;
  340. ; Returns: ;
  341. ; ;
  342. ; Error Returns: ;
  343. ; ;
  344. ; Registers Preserved: ;
  345. ; CX,DX,DI,SI,DS,ES ;
  346. ; ;
  347. ; Registers Destroyed: ;
  348. ; AX,BX ;
  349. ; ;
  350. ; Calls: ;
  351. ; ;
  352. ; History: ;
  353. ; ;
  354. ; Sun Jan 04, 1987 04:37:11p -by- David N. Weise [davidw] ;
  355. ; Added this nifty comment block. ;
  356. ;-----------------------------------------------------------------------;
  357. assumes ds, nothing
  358. assumes es, nothing
  359. cProc LockCurrentTask,<PUBLIC,FAR>
  360. ; ParmW lock
  361. cBegin nogen ; Crock to save space
  362. mov bx,sp
  363. mov ax,ss:[bx][4] ; get the argument
  364. push ds
  365. SetKernelDS
  366. or ax,ax
  367. jz short lct1
  368. mov ax,curTDB
  369. lct1:
  370. mov LockTDB,ax
  371. pop ds
  372. UnSetKernelDS
  373. ret 2
  374. cEnd nogen
  375. ;-----------------------------------------------------------------------;
  376. ; IsTaskLocked ;
  377. ; ;
  378. ; Another hack procedure to determine if the current task is locked. ;
  379. ; A non-NULL value is returned if the task is locked and NULL is ;
  380. ; returned is the task is not locked. ;
  381. ; ;
  382. ; Arguments: ;
  383. ; ; ;
  384. ; Returns: ;
  385. ; The value of LockTDB ;
  386. ; Error Returns: ;
  387. ; ;
  388. ; Registers Preserved: ;
  389. ; All but AX ;
  390. ; ;
  391. ; Registers Destroyed: ;
  392. ; AX ;
  393. ; ;
  394. ; Calls: ;
  395. ; ;
  396. ; History: ;
  397. ; ;
  398. ; (Tue 20-Oct-1987 : bobgu) Created this thing. ;
  399. ;-----------------------------------------------------------------------;
  400. assumes ds, nothing
  401. assumes es, nothing
  402. cProc IsTaskLocked,<PUBLIC,FAR>
  403. cBegin nogen
  404. push ds
  405. SetKernelDS
  406. mov ax,LockTDB
  407. pop ds
  408. UnSetKernelDS
  409. ret
  410. cEnd nogen
  411. ;-----------------------------------------------------------------------;
  412. ; SaveState ;
  413. ; ;
  414. ; Saves the state of the current MS-DOS process. This means the per ;
  415. ; task interrupt vectors, the drive and directory, EEMS land if any, ;
  416. ; and old app stuff if any. ;
  417. ; ;
  418. ; Arguments: ;
  419. ; parmW destination ;
  420. ; ;
  421. ; Returns: ;
  422. ; DS returned in AX. ;
  423. ; ;
  424. ; Error Returns: ;
  425. ; ;
  426. ; Registers Preserved: ;
  427. ; ;
  428. ; Registers Destroyed: ;
  429. ; ;
  430. ; Calls: ;
  431. ; ;
  432. ; History: ;
  433. ; ;
  434. ; Mon 07-Aug-1989 21:53:42 -by- David N. Weise [davidw] ;
  435. ; Removed the WinOldApp support. ;
  436. ; ;
  437. ; Tue Feb 03, 1987 08:21:53p -by- David N. Weise [davidw] ;
  438. ; Got rid of the rest of the DOS version dependencies. ;
  439. ; ;
  440. ; Thu Jan 22, 1987 03:15:15a -by- David N. Weise [davidw] ;
  441. ; Took out the saving of the ^C state, DTA address, and ErrorMode. ;
  442. ; ;
  443. ; Sun Jan 04, 1987 04:40:44p -by- David N. Weise [davidw] ;
  444. ; Added this nifty comment block. ;
  445. ;-----------------------------------------------------------------------;
  446. assumes ds, nothing
  447. assumes es, nothing
  448. cProc SaveState,<PUBLIC,NEAR>,<si,di,ds>
  449. parmW destination
  450. cBegin
  451. cld
  452. SetKernelDS
  453. mov ax,f8087
  454. UnSetKernelDS
  455. mov ds,destination
  456. or ax,ax
  457. jz short no_fstcw
  458. .8087
  459. fstcw ds:[TDB_FCW]
  460. no_fstcw:
  461. test ds:[TDB_Drive],10000000b; if hi bit set....
  462. jnz short ss_ret ; ...no need to get dir
  463. mov ah,19h
  464. int 21h
  465. mov dl,al
  466. inc dl
  467. or al,10000000b
  468. mov ds:[TDB_Drive],al ; save it (A=0, B=1, etc.)
  469. mov si,TDB_Directory
  470. mov byte ptr [si],'\' ; set "\"
  471. inc si
  472. mov ah,47h ; get current directory...
  473. int 21h
  474. jnc short ss_ret
  475. mov byte ptr [si-1],0 ; indicate error with null byte
  476. ss_ret: mov ax,ds
  477. cEnd
  478. cProc TaskSwitchProfileUpdate,<PUBLIC,NEAR>
  479. cBegin
  480. SetKernelDS es
  481. ;** See if we need to write out the profile string cache. We
  482. ;** do this at task switch time.
  483. cmp es:fProfileDirty, 0
  484. je short PU_NoFlushProfiles
  485. push es
  486. call WriteOutProfiles
  487. pop es
  488. PU_NoFlushProfiles:
  489. ;** Set the flag saying that the profile cache MAY be invalid.
  490. ;** If a task switch occurs, on the next Get/SetProfileXXX() we
  491. ;** will have to see if the file has been modified by this
  492. ;** (or any other) task
  493. mov es:fProfileMaybeStale,1
  494. cEnd
  495. assumes ds, nothing
  496. assumes es, nothing
  497. if PMODE32
  498. .386
  499. else
  500. .286
  501. endif
  502. cProc PokeAtSegments,<PUBLIC,NEAR>
  503. cBegin
  504. push ds
  505. push es
  506. pusha
  507. cCall GetFreeSpace,<2> ; Ignore discardable
  508. or dx, dx ; Insist on > 64k free
  509. if KDEBUG
  510. jz never_again
  511. else
  512. jz short never_again
  513. endif
  514. if PMODE32
  515. SetKernelDS
  516. test WinFlags[1], WF1_PAGING
  517. jz short have_room
  518. sub sp, 30h ; Room for info
  519. smov es, ss
  520. mov di, sp
  521. mov ax, 0500h ; Get Paging Info
  522. int 31h
  523. mov eax, es:[di][14h] ; Free pages
  524. add sp, 30h
  525. cmp eax, 16 ; Insist on 64k
  526. jb short never_again
  527. have_room:
  528. smov es, ds
  529. ResetKernelDS es
  530. else
  531. SetKernelDS es
  532. endif
  533. mov ds, hExehead
  534. UnsetKernelDS
  535. next_exe:
  536. mov cx, ds:[ne_cseg] ; Module has segments?
  537. jcxz no_segs ; no, on to next module
  538. mov di, 1 ; Segment number
  539. mov si, ds:[ne_segtab] ; Pointer to segment table
  540. next_seg:
  541. test ds:[si].ns_flags, NSLOADED ; This segment in memory?
  542. jnz short seg_here ; yes, look at next one
  543. test ds:[si].ns_flags, NSDISCARD ; Only load if discardable
  544. jz short seg_here ; Skip this one
  545. if KDEBUG
  546. push ds
  547. SetKernelDS
  548. mov fPreloadSeg, 1
  549. pop ds
  550. UnsetKernelDS
  551. endif
  552. cCall LoadSegment,<ds,di,-1,-1>
  553. if KDEBUG
  554. push ds
  555. SetKernelDS
  556. mov fPreloadSeg, 0
  557. pop ds
  558. UnsetKernelDS
  559. endif
  560. stc ; We loaded something!
  561. jmps all_done
  562. seg_here:
  563. lea si, [si + size NEW_SEG1] ; On to next segment
  564. inc di
  565. loop next_seg ; looked at all in this module?
  566. no_segs:
  567. mov cx, ds:[ne_pnextexe] ; On to next module
  568. jcxz all_done ; End of list?
  569. mov ax, ds
  570. mov ds, cx
  571. cmp ax, hShell ; Only boot time modules
  572. jne short next_exe
  573. UnSetKernelDS es
  574. never_again:
  575. SetKernelDS
  576. mov fPokeAtSegments, 0 ; That's all folks
  577. clc
  578. all_done:
  579. popa
  580. pop es
  581. pop ds
  582. cEnd
  583. sEnd CODE
  584. end