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.

176 lines
3.9 KiB

  1. ;
  2. ;
  3. ; Copyright (C) Microsoft Corporation, 1987
  4. ;
  5. ; This Module contains Proprietary Information of Microsoft
  6. ; Corporation and should be treated as Confidential.
  7. ;
  8. subttl emthread.asm - Emulator multi-thread support for OS/2
  9. page
  10. thread1static=1 ; set DS = EMULATOR_DATA for thread 1
  11. ; dynamically allocate data areas for other threads
  12. _DATA segment word public 'DATA'
  13. _DATA ends
  14. DGROUP group _DATA
  15. _DATA segment word public 'DATA'
  16. extrn __FPDSARRAY:WORD
  17. ifdef i386
  18. extrn __threadid:FWORD ; far pointer to ???? thread id
  19. else
  20. extrn __threadid:DWORD ; far pointer to WORD thread id
  21. endif
  22. _DATA ends
  23. dataoffset equ offset DGROUP:
  24. include os2dll.inc ; defines _SIGNAL_LOCK
  25. ; and other lock values;
  26. ; must be synchronized with
  27. ; \clib\include\86\os2dll.inc
  28. ; and \clib\include\os2dll.h
  29. extrn __lockf:FAR
  30. extrn __unlockf:FAR
  31. LOAD_DS_EDI macro
  32. local TIDOk, LoadDone
  33. ;
  34. ; loads ds:edi with far pointer to thread's DS selector
  35. ; (pointer into __FPDSARRAY)
  36. ;
  37. ; uses eax,edi,es,ds
  38. ;
  39. ; sets eax = 2 * (thread id)
  40. ;
  41. mov ax,DGROUP
  42. mov ds,ax ; set DS = DGROUP temporarily
  43. assume ds:DGROUP
  44. les edi,[__threadid] ; ES:eDI = far pointer to thread id
  45. mov ax,es:[edi] ; AX = thread id (far ptr to WORD)
  46. cmp ax, MAXTHREADID
  47. jbe TIDOk
  48. push ax
  49. call LoadDS_EDI
  50. pop ax
  51. shl ax, 1 ; thread id times 2
  52. jmp short LoadDone
  53. TIDOk:
  54. shl eax,1 ; thread id times 2
  55. mov edi,dataoffset __FPDSARRAY
  56. add edi,eax ; index into __FPDSARRAY
  57. LoadDone:
  58. endm
  59. LOADthreadDS macro
  60. ;
  61. ; loads thread's DS from __FPDSARRAY indexed by thread id
  62. ; preserves all registers except DS and eAX
  63. ;
  64. ; __FPDSARRAY[0] = MAXTHREAD
  65. ; __FPDSARRAY[i] = emulator DS for thread i, 1<=i<=MAXTHREAD
  66. ;
  67. push edi ; save eDI
  68. push es ; save ES
  69. LOAD_DS_EDI ; get pointer (ds:edi) to thread's DS
  70. mov ds,ds:[edi] ; set up DS to thread's data area
  71. assume ds:EMULATOR_DATA ; or dynamically allocated copy
  72. pop es
  73. pop edi ; restore DI
  74. endm
  75. ALLOCthreadDS macro
  76. pub allocperthread
  77. LOAD_DS_EDI ; get pointer into __FPDSARRAY
  78. ; eAX = 2 * (thread_id)
  79. ifdef thread1static
  80. ;
  81. ; for thread 1, use EMULATOR_DATA segment
  82. ;
  83. cmp eax,2 ; thread 1?
  84. jnz allocds ; no - dynamically allocate DS
  85. mov ax,EMULATOR_DATA ; yes - use static area
  86. mov ds:[edi],ax ; store new DS into __FPDSARRAY
  87. mov ds,ax
  88. assume ds:EMULATOR_DATA ; or dynamically allocated copy
  89. mov es,ax ; ES = DS = EMULATOR_DATA
  90. jmp allocdone
  91. else
  92. jmp allocds
  93. endif ;thread1static
  94. pub allocerror
  95. mov ax,-3 ; return allocation error
  96. stc
  97. ret
  98. ;
  99. ifdef thread1static
  100. ; for threads other than thread 1, allocate new DS from the system
  101. else
  102. ; for all threads, allocate new DS from the system
  103. endif
  104. ;
  105. pub allocds
  106. assume ds:DGROUP
  107. push offset __fptaskdata ; size of per-thread data area
  108. push ds ; ds:di = addr of thread's DS
  109. push edi
  110. push 0 ; non-shared segment
  111. os2call DOSALLOCSEG
  112. or ax,ax ; allocation error?
  113. jnz allocerror ; yes - cause thread init to fail
  114. mov di,ds:[edi] ; set ES = DS = thread's data selector
  115. mov ds,di
  116. mov es,di
  117. assume ds:EMULATOR_DATA ; or dynamically allocated copy
  118. pub allocdone
  119. ;
  120. ; ES = DS = selector for emulator data area
  121. ;
  122. mov edx,offset __fptaskdata ; dx = size of emulator data area
  123. sub edx,offset EMULATOR_DATA; jwm
  124. xor ax,ax ; prepare to zero out data segment
  125. xor edi,edi ; start at offset zero
  126. mov edi,offset EMULATOR_DATA; jwm : begin at the beginning
  127. mov ecx,edx ; cx = size of segment (even)
  128. shr ecx,1 ; halve it
  129. rep stosw ; zero it!
  130. endm
  131. FREEthreadDS macro
  132. pub freeperthread
  133. assume ds:EMULATOR_DATA ; or dynamically allocated copy
  134. ifdef thread1static
  135. mov ax,ds
  136. cmp ax,EMULATOR_DATA ; don't free thread 1's area
  137. je nofreeseg
  138. endif ;thread1static
  139. push ds
  140. os2call DOSFREESEG ; free per-thread emulator data area
  141. nofreeseg:
  142. LOAD_DS_EDI ; get pointer into __FPDSARRAY
  143. mov word ptr ds:[edi],0 ; zero out __FPDSARRAY element
  144. ; for the current thread
  145. assume ds:EMULATOR_DATA
  146. endm