semMALib.s
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:7k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* semMALib.s - i80x86 internal VxWorks mutex semaphore assembly library */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01f,20mar02,hdn  preserved previous state of the int enable bit (spr 74016)
  7. 01e,09nov01,pcm  added VxWorks semaphore events
  8. 01d,22aug01,hdn  added FUNC/FUNC_LABEL, replaced .align with .balign
  9. 01c,29jul96,sbs  Made windview conditionally compile.
  10. 01b,08aug94,hdn  added support for WindView.
  11. 01a,02jun93,hdn  extracted from semALib.s
  12. */
  13. /*
  14. DESCRIPTION
  15. This module contains internals to the VxWorks kernel.
  16. These routines have been coded in assembler because they are optimized for
  17. performance.
  18. */
  19. #define _ASMLANGUAGE
  20. #include "vxWorks.h"
  21. #include "asm.h"
  22. #include "private/taskLibP.h"
  23. #include "private/semLibP.h"
  24. .data
  25. .globl FUNC(copyright_wind_river)
  26. .long FUNC(copyright_wind_river)
  27. #ifndef PORTABLE
  28. /* externals */
  29. .globl FUNC(semIntRestrict)
  30. .globl FUNC(semInvalid)
  31. .globl FUNC(semMGiveKern)
  32. .globl FUNC(semMPendQPut)
  33. .globl FUNC(semTake)
  34. .globl FUNC(windExit)
  35. .globl VAR(semMGiveKernWork)
  36. /* internals */
  37. .globl GTEXT(semMGive) /* optimized mutex semaphore give */
  38. .globl GTEXT(semMTake) /* optimized mutex semaphore take */
  39. .text
  40. .balign 16
  41. /*******************************************************************************
  42. *
  43. * semIsInvalidUnlock - unlock interupts and call semInvalid ().
  44. */
  45. semIsInvalidUnlock:
  46. popfl /* UNLOCK INTERRUPTS */
  47. jmp FUNC(semInvalid) /* let C rtn do work and ret */
  48. /*******************************************************************************
  49. *
  50. * semMGive - optimized give of a mutex semaphore
  51. *
  52. * STATUS semMGive
  53. *    (
  54. *    SEM_ID semId /@ semaphore id to give @/
  55. *    )
  56. * INTERNAL
  57. * assumptions are:
  58. *  - %ecx = semId
  59. *  - %eax = 0
  60. */
  61. .balign 16,0x90
  62. semMRecurse:
  63. decw SEM_RECURSE(%ecx) /* decrement recurse count */
  64. popfl /* UNLOCK INTERRUPTS */
  65. ret
  66. .balign 16,0x90
  67. FUNC_LABEL(semMGive)
  68. cmpl FUNC(intCnt), %eax /* is it in ISR? */
  69. jne FUNC(semIntRestrict) /*   yes: let C do the work */
  70. movl FUNC(taskIdCurrent),%edx /* taskIdCurrent into %edx */
  71. pushfl /* save IF in EFLAGS */
  72. cli /* LOCK INTERRUPTS */
  73. cmpl $FUNC(semClass),(%ecx) /* check validity */
  74. #ifdef WV_INSTRUMENTATION
  75.         je objOkMGive /* object is okay */
  76. /* windview - check the validity of instrumented class */
  77.         cmpl $FUNC(semInstClass),(%ecx) /* check validity */
  78. jne  semIsInvalidUnlock /* semaphore id error */
  79. objOkMGive:
  80. #else 
  81.         jne     semIsInvalidUnlock /* semaphore id error */
  82. #endif  /* WV_INSTRUMENTATION */
  83. cmpl SEM_STATE(%ecx),%edx /* taskIdCurrent is owner? */
  84. jne semIsInvalidUnlock /* SEM_INVALID_OPERATION */
  85. cmpw SEM_RECURSE(%ecx), %ax /* if recurse count > 0 */
  86. jne semMRecurse /* handle recursion */
  87. semMInvCheck:
  88. testb $0x8,SEM_OPTIONS(%ecx) /* SEM_INVERSION_SAFE? */
  89. je semMStateSet /* if not, test semQ */
  90. decl WIND_TCB_MUTEX_CNT(%edx) /* decrement mutex count */
  91. jne semMStateSet /* if nonzero, test semQ */
  92. movl WIND_TCB_PRIORITY(%edx),%eax /* put priority in %eax */
  93. subl WIND_TCB_PRI_NORMAL(%edx),%eax /* subtract normal priority */
  94. je semMStateSet /* if same, test semQ */
  95. movl $4,%eax /* or in PRIORITY_RESORT */
  96. semMStateSet:
  97. pushl SEM_Q_HEAD(%ecx) /* update semaphore state */
  98. popl SEM_STATE(%ecx)
  99. cmpl $0,SEM_STATE(%ecx)
  100. je semMEventRsrcSend /* Jump if state change */
  101. incl %eax /* Else, OR in Q_GET */
  102. jmp semMDelSafe /* Jump to semMDelSafe */
  103. .balign 16, 0x90
  104. semMEventRsrcSend:
  105. cmpl $0, SEM_EVENTS_TASKID (%ecx)
  106. je semMDelSafe /* Jump if taskId is NULL */
  107. addl $SEM_M_SEND_EVENTS, %eax /* Else, OR in SEND_EVENTS */
  108. semMDelSafe:
  109. testb $0x4,SEM_OPTIONS(%ecx) /* SEM_DELETE_SAFE? */
  110. je semMShortCut /* check for short cut */
  111. decl WIND_TCB_SAFE_CNT(%edx) /* decrement safety count */
  112. jne semMShortCut /* check for short cut */
  113. cmpl $0,WIND_TCB_SAFETY_Q_HEAD(%edx) /* check for pended deleters */
  114. je semMShortCut /* check for short cut */
  115. addl $2,%eax /* OR in SAFETY_Q_FLUSH */
  116. semMShortCut:
  117. testl %eax,%eax /* any work for kernel level? */
  118. jne semMKernWork /* enter kernel if any work */
  119. popfl /* UNLOCK INTERRUPTS */
  120. ret /* %eax is still 0 for OK */
  121. .balign 16,0x90
  122. semMKernWork:
  123. movl $1,FUNC(kernelState) /* KERNEL ENTER */
  124. popfl /* UNLOCK INTERRUPTS */
  125. movl %eax,FUNC(semMGiveKernWork) /* setup work for semMGiveKern*/
  126. jmp FUNC(semMGiveKern) /* finish semMGive in C */
  127. /*******************************************************************************
  128. *
  129. * semMTake - optimized take of a mutex semaphore
  130. *
  131. * STATUS semMTake
  132. *    (
  133. *    SEM_ID semId, /@ semaphore id to give @/
  134. *    int  timeout /@ timeout in ticks @/
  135. *    )
  136. * INTERNAL
  137. * assumptions are:
  138. *  - %ecx = semId
  139. */
  140. .balign 16,0x90
  141. FUNC_LABEL(semMTake)
  142. cmpl $0, FUNC(intCnt) /* is it in ISR? */
  143. jne FUNC(semIntRestrict) /*   yes: let C do the work */
  144. movl FUNC(taskIdCurrent),%edx /* taskIdCurrent into %edx */
  145. pushfl /* save IF in EFLAGS */
  146. cli /* LOCK INTERRUPTS */
  147. cmpl $FUNC(semClass),(%ecx) /* check validity */
  148. #ifdef WV_INSTRUMENTATION
  149.         je      objOkMTake /* object is okay */
  150. /* windview - check the validity of instrumented class */
  151.         cmpl    $FUNC(semInstClass),(%ecx) /* check validity */
  152.         jne     semIsInvalidUnlock /* invalid semaphore */
  153. objOkMTake:
  154. #else
  155.         jne     semIsInvalidUnlock              /* invalid semaphore */
  156. #endif  /* WV_INSTRUMENTATION */
  157. movl SEM_STATE(%ecx),%eax /* test for owner */
  158. testl %eax,%eax /* is the sem empty? */
  159. jne semMEmpty /* sem is owned, is it ours? */
  160. movl %edx,SEM_STATE(%ecx) /* we now own semaphore */
  161. testb $0x4,SEM_OPTIONS(%ecx) /* SEM_DELETE_SAFE? */
  162. je semMPriCheck /* semMPriCheck */
  163. incl WIND_TCB_SAFE_CNT(%edx) /* bump safety count */
  164. semMPriCheck:
  165. testb $0x8,SEM_OPTIONS(%ecx) /* SEM_INVERSION_SAFE? */
  166. je semMDone /* if not, skip increment */
  167. incl WIND_TCB_MUTEX_CNT(%edx) /* bump priority mutex count */
  168. semMDone:
  169. popfl /* UNLOCK INTERRUPTS */
  170. ret /* %eax is still 0 for OK */
  171. .balign 16,0x90
  172. semMEmpty:
  173. subl %edx,%eax /* recursive take */
  174. jne semMQUnlockPut /* if not, block */
  175. incw SEM_RECURSE(%ecx) /* increment recurse count */
  176. popfl /* UNLOCK INTERRUPTS */
  177. ret /* %eax is still 0 for OK */
  178. .balign 16,0x90
  179. semMQUnlockPut:
  180. movl $1,FUNC(kernelState) /* KERNEL ENTER */
  181. popfl /* UNLOCK INTERRUPTS */
  182. pushl SP_ARG2(%esp) /* push the timeout */
  183. pushl %ecx /* push the semId */
  184. call FUNC(semMPendQPut) /* do as much in C as possible*/
  185. addl $8,%esp /* clean up */
  186. testl %eax,%eax /* test return value */
  187. jne semMFail /* if !OK, exit kernel, ERROR */
  188. call FUNC(windExit) /* KERNEL EXIT */
  189. testl  %eax,%eax                  /* windExit() == OK -> return */
  190. jne semMWindExitNotOk
  191. ret /* EAX = OK */
  192. .balign 16,0x90
  193. semMWindExitNotOk:
  194. cmpl    $1,%eax                  /* check for RESTART retVal */
  195. je      semMRestart
  196. ret  /* EAX = ERROR */
  197. .balign 16,0x90
  198. semMRestart:
  199. pushl SP_ARG2(%esp) /* push the timeout */
  200. movl FUNC(_func_sigTimeoutRecalc),%eax /* addr of recalc routine */
  201. call *%eax /* recalc the timeout */
  202. addl $4,%esp /* clean up */
  203. movl %eax,SP_ARG2(%esp) /* restore the timeout */
  204. jmp FUNC(semTake) /* start the whole thing over */
  205. .balign 16,0x90
  206. semMFail:
  207. call FUNC(windExit) /* KERNEL EXIT */
  208. movl $-1,%eax /* return ERROR */
  209. ret /* failed */
  210. #endif /* !PORTABLE */