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

VxWorks

开发平台:

C/C++

  1. /* semALib.s - i80x86 internal VxWorks binary semaphore assembly library */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01l,20mar02,hdn  preserved previous state of the int enable bit (spr 74016)
  7. 01k,09nov01,pcm  added VxWorks semaphore events
  8. 01j,23aug01,hdn  added FUNC/FUNC_LABEL, replaced .align with .balign
  9. 01i,30apr98,cjtc bug fixes in semaphore instrumentation
  10. 01h,28apr98,pr   fixed problem with registers in WV code.
  11. 01g,16apr98,pr   cleanup.
  12. 01f,17feb98,pr   added WindView 2.0 code.
  13. 01f,24jun97,sub  fixed semTakeGlobal and semGiveGlobal for VxMP - SPR # 8833
  14. 01e,29jul96,sbs  Made windview conditionally compile.
  15. 01d,08aug94,hdn  added support for WindView.
  16. 01c,02jun93,hdn  split into sem[CM]ALib.s to increase modularity.
  17.  added shared memory semaphores support.
  18.  added signal restart.
  19.  updated to 5.1
  20.   - fixed #else and #endif
  21.   - changed ASMLANGUAGE to _ASMLANGUAGE
  22.   - changed copyright notice
  23. 01b,13oct92,hdn  debugged.
  24. 01a,07apr92,hdn  written based on TRON version.
  25. */
  26. /*
  27. DESCRIPTION
  28. This module contains internals to the VxWorks kernel.
  29. These routines have been coded in assembler because they are optimized for
  30. performance.
  31. */
  32. #define _ASMLANGUAGE
  33. #include "vxWorks.h"
  34. #include "vwModNum.h"
  35. #include "asm.h"
  36. #include "eventLib.h"
  37. #include "semLib.h"
  38. #include "private/semLibP.h"
  39. #include "private/classLibP.h"
  40. #include "private/taskLibP.h"
  41. #include "private/eventP.h"
  42. .data
  43. .globl FUNC(copyright_wind_river)
  44. .long FUNC(copyright_wind_river)
  45. #ifndef PORTABLE
  46. /* externals */
  47. .globl FUNC(semIntRestrict)
  48. .globl FUNC(semInvalid)
  49. .globl FUNC(semGiveDefer)
  50. .globl FUNC(windExit)
  51. .globl FUNC(windPendQPut)
  52. .globl FUNC(windPendQGet)
  53. .globl VAR(smObjPoolMinusOne)
  54. /* internals */
  55. .globl GTEXT(semGive) /* optimized semGive demultiplexer */
  56. .globl GTEXT(semTake) /* optimized semTake demultiplexer */
  57. .globl GTEXT(semBGive) /* optimized binary semaphore give */
  58. .globl GTEXT(semBTake) /* optimized binary semaphore take */
  59. .globl GTEXT(semQGet) /* semaphore queue get routine */
  60. .globl GTEXT(semQPut) /* semaphore queue put routine */
  61. .globl GTEXT(semOTake) /* optimized old semaphore take */
  62. .globl GTEXT(semClear) /* optimized old semaphore semClear */
  63. .globl GTEXT(semEvRsrcSend)
  64. .text
  65. .balign 16
  66. /*******************************************************************************
  67. *
  68. * semGiveKern - add give routine to work queue
  69. *
  70. */
  71. semGiveKern:
  72. jmp FUNC(semGiveDefer) /* let C rtn defer work and ret */
  73. /*******************************************************************************
  74. *
  75. * semGive - give a semaphore
  76. *
  77. *
  78. *STATUS semGive (semId)
  79. *    SEM_ID semId; /* semaphore id to give *
  80. */
  81. .balign 16, 0x90
  82. semGiveReturn: /* This small block is before the semGive */
  83. popfl /* as the default branch for a conditional */ 
  84. ret /* jump is jump back. */
  85. .balign 16,0x90
  86. FUNC_LABEL(semGive)
  87. movl SP_ARG1(%esp),%ecx /* semId goes into %ecx */
  88. testl $1,%ecx /* is it a global semId */
  89. jne semGiveGlobal /* if LSB is 1, its a global sem */
  90. xorl %edx, %edx /* Clear edx */
  91. #ifdef WV_INSTRUMENTATION
  92. /* 
  93.  * windview instrumentation - BEGIN
  94.  * semGive: object status class
  95.  */
  96. cmpl FUNC(evtAction), %edx /*  is WindView on? */
  97. je noSemGiveEvt
  98.         cmpl    $FUNC(semClass),(%ecx) /* check validity */
  99.         je objOkGive
  100.         cmpl $FUNC(semInstClass),(%ecx) /* check validity */
  101.         jne     noSemGiveEvt /* invalid semaphore */
  102. objOkGive:
  103. movl $ WV_CLASS_3_ON,%eax
  104.         andl    FUNC(wvEvtClass),%eax /* is event collection on? */
  105.         cmpl    $ WV_CLASS_3_ON,%eax /* is event collection on? */
  106. jne trgCheckSemGive
  107. pushl %eax
  108. pushl %ecx /* semId */
  109. pushl %edx
  110. /* is this semaphore object instrumented? */
  111. movl (%ecx),%eax /* %ecx - semId */
  112. cmpl $0,SEM_INST_RTN(%eax) /* event routine attached? */
  113. je trgNoSemGive
  114. /* log event for this object */
  115. pushl %edx /* $0 */
  116. pushl %edx /* $0 */
  117. movw SEM_RECURSE(%ecx),%dx /* recursively called */
  118. pushl %edx
  119. movl SEM_STATE(%ecx),%edx /* state/count/owner */
  120. pushl %edx
  121. pushl %ecx /* semId */
  122. pushl $ 3 /* number of paramters */
  123. pushl $ EVENT_SEMGIVE /* EVENT_SEMGIVE, event id */
  124. movl SEM_INST_RTN(%eax),%edx /* get logging routine */
  125. call *%edx /* call routine */
  126. addl $28,%esp
  127. trgNoSemGive:
  128. popl %edx
  129. popl %ecx /* semId */
  130. popl %eax
  131. trgCheckSemGive:
  132. movl $ TRG_CLASS_3,%eax     
  133. orl  $ TRG_ON,%eax
  134.         cmpl    FUNC(trgEvtClass),%eax /* any trigger? */
  135. jne noSemGiveEvt
  136.         movl    FUNC(_func_trgCheck),%eax    /* triggering routine */
  137.         cmpl    %edx, %eax /* Note: %edx = 0 */
  138.         je      noSemGiveEvt
  139. pushl %ecx /* semId */
  140. pushl %edx
  141.         pushl   %edx /* $0 */
  142.         pushl   %edx /* $0 */
  143. movw SEM_RECURSE(%ecx),%dx /* recursively called */
  144. pushl %edx
  145. movl SEM_STATE(%ecx),%edx /* state/count/owner */
  146. pushl %edx
  147. pushl %ecx /* semId */
  148. pushl %ecx /* objId */
  149.         pushl   $ TRG_CLASS3_INDEX      /* TRG_CLASS3_INDEX */
  150. pushl $ EVENT_SEMGIVE /* EVENT_SEMGIVE, event id */
  151.         call    *%eax                   /* call triggering routine */
  152.         addl    $32,%esp
  153. popl %edx
  154. popl %ecx /* semId */
  155. noSemGiveEvt:
  156. /* windview instrumentation - END */
  157. #endif  /* WV_INSTRUMENTATION */
  158. movl FUNC(kernelState),%eax /* are we in kernel state? */
  159. cmpl %edx, %eax /* %edx already 0 */
  160. jne semGiveKern /* %eax = 0 if we are not */
  161. movb SEM_TYPE(%ecx),%dl /* put the sem class into %edx */
  162. andb $ SEM_TYPE_MASK,%dl /* mask %edx to MAX_SEM_TYPE value */
  163. jne semGiveNotBinary /* optimize for BINARY if %edx == 0 */
  164. /* 
  165.  * BINARY SEMAPHORE OPTIMIZATION
  166.  * assumptions are:
  167.  *  - %ecx = semId (%ecx is a volatile register)
  168.  */
  169. FUNC_LABEL(semBGive)
  170. pushfl /* save IF in EFLAGS */
  171. cli /* LOCK INTERRUPTS */
  172. cmpl    $FUNC(semClass),(%ecx) /* check validity */
  173. /*
  174.  * FIXME-PR: if this is going to be part of the kernel 
  175.  *           permanently, it should be rearranged. It  
  176.  *           does an extra instruction that is not needed.
  177.  */
  178. #ifdef WV_INSTRUMENTATION
  179. je objOkBGive /* object is okay */
  180. /* windview - check the validity of instrumented class */
  181. cmpl    $FUNC(semInstClass),(%ecx) /* check validity */
  182. jne     semIsInvalidUnlock /* semaphore id error */
  183. objOkBGive:
  184. #else
  185. jne     semIsInvalidUnlock /* invalid semaphore */
  186. #endif  /* WV_INSTRUMENTATION */
  187. movl    SEM_Q_HEAD(%ecx),%eax
  188. movl    SEM_STATE(%ecx), %edx /* %edx = previous semOwner */
  189. movl    %eax,SEM_STATE(%ecx)
  190. testl   %eax, %eax /* is new semOwner NULL? */
  191. jne     FUNC(semQGet) /* if not empty, get from q */
  192. cmpl    SEM_EVENTS_TASKID (%ecx), %eax
  193. jz     semGiveReturn /* skip if taskId == NULL */
  194. testl   %edx, %edx /* is prev semOwner NULL? */
  195. jnz     FUNC(semEvRsrcSend) /* if not, jump */
  196. popfl /* UNLOCK INTERRUPTS */
  197. ret /* return OK */
  198. .balign 16,0x90
  199. semGiveNotBinary:
  200.         /*
  201.  * Call semGive indirectly via semGiveTbl.  Note that the index could
  202.  * equal zero after it is masked.  semBGive is the zeroeth element
  203.  * of the table, but for it to function correctly in the optimized
  204.  * version above, we must be certain not to clobber %ecx.  Note, also
  205.  * that old semaphores will also call semBGive above.
  206.  */
  207. movl FUNC(semGiveTbl)(,%edx,4),%edx
  208. jmp *%edx     /* invoke give rtn, it will ret */
  209. .balign 16,0x90
  210. semGiveGlobal:
  211. addl FUNC(smObjPoolMinusOne),%ecx /* convert id to local addr */
  212. movb 7(%ecx),%dl     /* get semaphore type in %dl */
  213.             /* offset 7 is used as the type
  214.      * is stored in  network order
  215.      */
  216. andl $ SEM_TYPE_MASK,%edx     /* mask %edx to MAX_SEM_TYPE */
  217. movl FUNC(semGiveTbl)(,%edx,4),%edx /* %edx is the give rtn. */
  218. pushl %ecx     /* push converted semId */
  219. call *%edx     /* call appropriate give rtn. */
  220. addl $4,%esp     /* clean up */
  221. ret
  222. /*******************************************************************************
  223. *
  224. * semEvRsrcSend - send a semaphore event on semGive
  225. *
  226. * This sub-routine is only executed if a semaphore state change has occurred,
  227. * and semId->events.taskId is not NULL.
  228. *
  229. * INTERNAL
  230. * assumptions are:
  231. *  - %ecx = semId (%ecx is a volatile register)
  232. *  - %eax = 0
  233. */
  234. .balign 16, 0x90
  235. FUNC_LABEL(semEvRsrcSend)
  236. movl $1, FUNC(kernelState) /* ENTER KERNEL */
  237. popfl /* UNLOCK INTERRUPTS */
  238. movl FUNC(errno), %eax
  239. pushl %esi /* Save %esi */
  240. pushl %edi /* Save %edi */
  241. pushl %ebx /* Save %ebx */
  242. pushl %eax /* Save errno */
  243. movl %ecx, %esi /* %esi = semId */
  244. /*
  245.  * Both semId->events.options and semId->options are being pushed
  246.  * onto the stack.  But where is semId->options?  SEM_TYPE is located
  247.  * at offset 0x04, and SEM_OPTIONS is located at offset 0x05.  As the 
  248.  * x86 series is little-endian, semId->options will be loaded into the
  249.  * %bh portion of the %ebx register.  It should also be noted that both
  250.  * semId->options and semId->events.options are a single byte.
  251.  */
  252. movl SEM_EVENTS_OPTIONS (%ecx), %edi /* Get semId->events.options */
  253. movl SEM_TYPE (%ecx), %ebx /* Get semId->options */
  254. movl SEM_EVENTS_REGISTERED (%ecx), %edx
  255. movl SEM_EVENTS_TASKID (%ecx), %eax
  256. pushl %edx /* semId->events.registered param */
  257. pushl %eax /* semId->events.taskId param */
  258. call FUNC(eventRsrcSend) /* eventRsrcSend (%eax, %edx) */
  259. addl $8, %esp /* Remove params from stack */
  260. /*
  261.  * This next block does the C code
  262.  * if ((evSendStatus != OK) && !(semOptions & EVENT_SEND_NOTIFY_ERROR))
  263.  * Two tests can be condensed into one since ...
  264.  * OK & x = 0, and ERROR & x = x
  265.  * Thus (evSendStatus & semOptions & EVENT_SEND_NOTIFY_ERROR) works.
  266.  * To avoid extra jumps (and flushing of the pipeline), the setXX
  267.  * commands are used.
  268.  */
  269. movl %eax, %edx /* edx = %eax (backup) */
  270. xorl %ecx, %ecx /* Clear <retStatus> */
  271. andl %ebx, %eax /* %eax = {0, semOptions << 8} */
  272. testl $(SEM_EVENTSEND_ERR_NOTIFY << 8), %eax
  273. setz %cl /* 1 if will return OK, 0 if ERROR */
  274. /*
  275.  * "if ((evtOptions & EVENTS_SEND_ONCE) || (evSendStatus != OK))"
  276.  * combined into one test.  semId->events.taskId is cleared if the 
  277.  * if-statement was TRUE.  No branching--cool.
  278.  */
  279. xorl %eax, %eax /* Clear %eax */
  280. decl %ecx /* retStatus = {OK, ERROR} */
  281. orl %edi, %edx /* Combine two tests into one */
  282. incl %eax /* %eax  = $EVENTS_SEND_ONCE */
  283. movl $S_eventLib_EVENTSEND_FAILED, %edi /* new errno */
  284. andl %edx, %eax /* %eax = {1,0} */
  285. popl %ebx /* old <errno> */
  286. decl %eax /* %eax = {0x0, 0xffffffff} */
  287. subl %ebx, %edi /* new <errno> - old <errno> */
  288. andl %eax, SEM_EVENTS_TASKID (%esi) /* {0, unchanged} */
  289. andl %ecx, %edi /* %edi = {0, new errno - old errno} */
  290. movl %ecx, %esi /* Save <retStatus> */
  291. addl %ebx, %edi /* %edi = {old errno, new errno} */
  292. call FUNC(windExit) /* EXIT KERNEL */
  293. movl %edi, FUNC(errno) /* Restore errno */
  294. movl %esi, %eax /* Restore <retStatus> */
  295. popl %ebx /* Restore %ebx */
  296. popl %edi /* Restore %edi */
  297. popl %esi /* Restore %esi */
  298. ret
  299. /*******************************************************************************
  300. *
  301. * semIsInvalid - unlock interupts and call semInvalid ().
  302. */
  303. .balign 16,0x90
  304. semIsInvalidUnlock:
  305. popfl /* UNLOCK INTERRUPTS */
  306. semIsInvalid:
  307. jmp FUNC(semInvalid) /* let C rtn do work and ret */
  308. /*******************************************************************************
  309. *
  310. * semTake - take a semaphore
  311. *
  312. * STATUS semTake
  313. * (
  314. * SEM_ID semId, /@ semaphore ID to give @/
  315. * int  timeout  /@ timeout in ticks @/
  316. * )
  317. */
  318. .balign 16,0x90
  319. FUNC_LABEL(semTake)
  320. movl SP_ARG1(%esp),%ecx /* semId goes into %ecx */
  321. testl $1,%ecx /* is it a global semId */
  322. jne semTakeGlobal /* if LSB is 1, its a global sem */
  323. #ifdef WV_INSTRUMENTATION
  324.         /* 
  325.  * windview instrumentation - BEGIN
  326.          * semTake: object status class
  327.          */
  328. cmpl $0,FUNC(evtAction) /* is WindView on? */
  329.         je noSemTakeEvt
  330.         cmpl $FUNC(semClass),(%ecx) /* check validity */
  331.         je objOkTake
  332.         cmpl $FUNC(semInstClass),(%ecx) /* check validity */
  333.         jne     noSemTakeEvt /* invalid semaphore */
  334. objOkTake:
  335. movl $ WV_CLASS_3_ON,%eax
  336.         andl    FUNC(wvEvtClass),%eax /* is event collection on? */
  337.         cmpl    $ WV_CLASS_3_ON,%eax /* is event collection on? */
  338. jne trgCheckSemTake
  339. pushl %eax
  340. pushl %ecx /* semId */
  341. pushl %edx
  342.         /* is this semaphore object instrumented? */
  343.         movl (%ecx),%eax /* %ecx - semId */
  344.         cmpl $0,SEM_INST_RTN(%eax) /* event routine attached? */
  345. je trgNoSemTake
  346.         /* log event for this object */
  347.         pushl $0
  348.         pushl $0
  349.         movl $0,%edx
  350.         movw SEM_RECURSE(%ecx),%dx /* recursively called */
  351.         pushl %edx
  352.         movl SEM_STATE(%ecx),%edx /* state/count/owner */
  353.         pushl %edx
  354.         pushl %ecx /* semId */
  355. pushl $ 3 /* number of paramters */
  356. pushl $ EVENT_SEMTAKE /* EVENT_SEMTAKE, event id */
  357.         movl SEM_INST_RTN(%eax),%edx /* get logging routine */
  358.         call *%edx /* call routine */
  359.         addl $28,%esp
  360. trgNoSemTake:
  361. popl %edx
  362. popl %ecx /* semId */
  363. popl %eax
  364. trgCheckSemTake:
  365. movl $ TRG_CLASS_3,%eax     
  366. orl  $ TRG_ON,%eax
  367.         cmpl    FUNC(trgEvtClass),%eax /* any trigger? */
  368. jne noSemTakeEvt
  369.         movl    FUNC(_func_trgCheck),%eax /* triggering routine */
  370.         cmpl    $0,%eax
  371.         je      noSemTakeEvt
  372. pushl %ecx /* semId */
  373. pushl %edx
  374.         pushl   $ 0                     /* 0 */
  375.         pushl   $ 0                     /* 0 */
  376.         movl $0,%edx
  377.         movw SEM_RECURSE(%ecx),%dx /* recursively called */
  378.         pushl %edx
  379.         movl SEM_STATE(%ecx),%edx /* state/count/owner */
  380.         pushl %edx
  381.         pushl %ecx /* semId */
  382. pushl %ecx /* objId */
  383.         pushl   $ TRG_CLASS3_INDEX      /* TRG_CLASS3_INDEX */
  384. pushl $ EVENT_SEMTAKE /* EVENT_SEMTAKE, event id */
  385.         call    *%eax                   /* call triggering routine */
  386.         addl    $32,%esp
  387. popl %edx
  388. popl %ecx /* semId */
  389. noSemTakeEvt:
  390.         /* windview instrumentation - END */
  391. #endif  /* WV_INSTRUMENTATION */
  392. movb SEM_TYPE(%ecx),%dl /* get semaphore class into %edx */
  393. andl $ SEM_TYPE_MASK,%edx /* mask %edx to sane value */
  394. jne semTakeNotBinary /* optimize binary semaphore %edx==0 */
  395. /* 
  396.  * BINARY SEMAPHORE OPTIMIZATION
  397.  * assumptions are:
  398.          *  - %ecx = semId (%ecx is a volatile register)
  399.  */
  400. FUNC_LABEL(semBTake)
  401. cmpl $0, FUNC(intCnt) /* is it in ISR? */
  402. jne FUNC(semIntRestrict) /*   yes: let C do the work */
  403. pushfl /* save IF in EFLAGS */
  404. cli /* LOCK INTERRUPTS */
  405. cmpl $FUNC(semClass),(%ecx) /* check validity */
  406. #ifdef WV_INSTRUMENTATION
  407.          je objOkBTake /* object is okay */
  408. /* windview - check the validity of instrumented class */
  409.          cmpl $FUNC(semInstClass),(%ecx) /* check validity */
  410.          jne semIsInvalidUnlock /* semaphore id error */
  411. objOkBTake:
  412. #else
  413.                 jne     semIsInvalidUnlock      /* invalid semaphore */
  414. #endif  /* WV_INSTRUMENTATION */
  415. movl SEM_STATE(%ecx),%eax /* test for owner */
  416. testl %eax,%eax /* is the sem owned? */
  417. jne FUNC(semQPut) /* if sem is owned we block */
  418. movl FUNC(taskIdCurrent),%edx
  419. movl %edx,SEM_STATE(%ecx) /* set the owner */
  420. popfl /* UNLOCK INTERRUPTS */
  421. ret /* %eax is still 0 for OK */
  422. .balign 16,0x90
  423. semTakeNotBinary:
  424. movl FUNC(semTakeTbl)(,%edx,4),%edx
  425. jmp *%edx /* invoke take rtn, it will ret */
  426. .balign 16,0x90
  427. semTakeGlobal:
  428. addl FUNC(smObjPoolMinusOne),%ecx /* convert id to local addr */
  429. movb 7(%ecx),%dl /* get semaphore type in %dl */
  430.         /* offset 7 is used as the type
  431.  * is stored in  network order
  432.  */
  433. andl $ SEM_TYPE_MASK,%edx /* mask %edx to MAX_SEM_TYPE */
  434. movl FUNC(semTakeTbl)(,%edx,4),%edx /* %edx is the take rtn. */
  435. pushl SP_ARG2(%esp) /* push timeout */
  436. pushl %ecx /* push converted semId */
  437. call *%edx /* call appropriate take rtn. */
  438. addl $8,%esp    /* clean up */
  439. ret
  440. /*******************************************************************************
  441. *
  442. * semQGet - unblock a task from the semaphore queue head
  443. *
  444. * INTERNAL
  445. * assumptions are:
  446. *  - %ecx = semId (%ecx is a volatile register)
  447. *  - (%esp + 0x0) = EFLAGS
  448. *  - (%esp + 0x4) = retAddr
  449. *  - (%esp + 0x8) = semId
  450. */
  451. .balign 16,0x90
  452. FUNC_LABEL(semQGet)
  453. movl $1,FUNC(kernelState) /* KERNEL ENTER */
  454. #ifdef WV_INSTRUMENTATION
  455.         /* 
  456.  * windview instrumentation - BEGIN
  457.          * semGive: task transition state class
  458.          */
  459. cmpl $0,FUNC(evtAction) /* is WindView on? */
  460. je noSemQGetEvt
  461. movl $ WV_CLASS_2_ON,%eax
  462.         andl    FUNC(wvEvtClass),%eax /* is event collection on? */
  463.         cmpl    $ WV_CLASS_2_ON,%eax /* is event collection on? */
  464. jne trgCheckSemQGet
  465. movl FUNC(_func_evtLogM1),%edx /* event log routine */
  466. cmpl $0,%edx
  467. je noSemQGetEvt
  468. pushl %ecx /* push semId */
  469. pushl $ EVENT_OBJ_SEMGIVE /* EVENT_OBJ_SEMGIVE */
  470. call *%edx /* call event log routine */
  471. addl $4,%esp /* restore stack pointer */
  472.         popl %ecx         /* pop semId */
  473. trgCheckSemQGet:
  474. movl $ TRG_CLASS_2,%eax     
  475. orl  $ TRG_ON,%eax
  476.         cmpl    FUNC(trgEvtClass),%eax /* any trigger? */
  477. jne noSemQGetEvt
  478.         movl    FUNC(_func_trgCheck),%edx /* triggering routine */
  479.         cmpl    $0,%edx
  480.         je      noSemQGetEvt
  481. xorl %eax, %eax /* Clear %eax */
  482. pushl %ecx /* semId */
  483.         pushl   %eax /* 0 */
  484.         pushl   %eax /* 0 */
  485.         pushl   %eax /* 0 */
  486.         pushl   %eax /* 0 */
  487. pushl %ecx /* push semId */
  488. pushl %ecx /* objId */
  489.         pushl   $ TRG_CLASS2_INDEX      /* TRG_CLASS3_INDEX */
  490. pushl $ EVENT_OBJ_SEMGIVE /* EVENT_OBJ_SEMGIVE */
  491. call *%edx /* call triggering routine */
  492.         addl    $32,%esp
  493. popl %ecx /* semId */
  494. noSemQGetEvt:
  495.         /* windview instrumentation - END */
  496. #endif  /* WV_INSTRUMENTATION */
  497. popfl /* UNLOCK INTERRUPTS */
  498. leal SEM_Q_HEAD(%ecx),%edx
  499. pushl %edx /* push the pointer to qHead */
  500. call FUNC(windPendQGet) /* unblock someone */
  501. addl $4,%esp /* clean up */
  502. call FUNC(windExit) /* KERNEL EXIT */
  503. ret          /* windExit sets %eax */
  504. /*******************************************************************************
  505. *
  506. * semQPut - block current task on the semaphore queue head
  507. *
  508. * INTERNAL
  509. * assumptions are:
  510. *  - %ecx = semId (%ecx is a volatile register)
  511. *  - (%esp + 0x0) = EFLAGS
  512. *  - (%esp + 0x4) = retAddr
  513. *  - (%esp + 0x8) = semId
  514. *  - (%esp + 0xc) = timeout
  515. */
  516. .balign 16,0x90
  517. FUNC_LABEL(semQPut)
  518. movl $1,FUNC(kernelState) /* KERNEL ENTER */
  519. #ifdef WV_INSTRUMENTATION
  520.         /* 
  521.  * windview instrumentation - BEGIN
  522.          * semTake: task transition state class
  523.          */
  524. cmpl $0,FUNC(evtAction) /* is WindView on? */
  525. je noSemQPutEvt
  526. movl $ WV_CLASS_2_ON,%eax
  527.         andl    FUNC(wvEvtClass),%eax /* is event collection on? */
  528.         cmpl    $ WV_CLASS_2_ON,%eax /* is event collection on? */
  529. jne trgCheckSemQPut
  530.         movl FUNC(_func_evtLogM1),%edx /* call event log routine */
  531. cmpl $0,%edx
  532.         je trgCheckSemQPut
  533.         pushl %ecx /* push semId */
  534.         pushl $ EVENT_OBJ_SEMTAKE /* EVENT_OBJ_SEMTAKE */
  535.         call *%edx
  536.         addl $4,%esp /* restore stack pointer */
  537.         popl %ecx /* pop semId */
  538. trgCheckSemQPut:
  539. movl $ TRG_CLASS_2,%eax     
  540. orl  $ TRG_ON,%eax
  541.         cmpl    FUNC(trgEvtClass),%eax /* any trigger? */
  542. jne noSemQPutEvt
  543.         movl    FUNC(_func_trgCheck),%edx /* triggering routine */
  544.         cmpl    $0,%edx
  545.         je      noSemQPutEvt
  546. pushl %ecx /* semId */
  547.         pushl   $ 0                     /* 0 */
  548.         pushl   $ 0                     /* 0 */
  549.         pushl   $ 0                     /* 0 */
  550.         pushl   $ 0                     /* 0 */
  551. pushl %ecx /* push semId */
  552. pushl %ecx /* objId */
  553.         pushl   $ TRG_CLASS2_INDEX      /* TRG_CLASS3_INDEX */
  554. pushl $ EVENT_OBJ_SEMTAKE /* EVENT_OBJ_SEMTAKE */
  555. call *%edx /* call triggering routine */
  556.         addl    $32,%esp
  557. popl %ecx /* semId */
  558. noSemQPutEvt:
  559.         /* windview instrumentation - END */
  560. #endif  /* WV_INSTRUMENTATION */
  561. popfl /* UNLOCK INTERRUPTS */
  562. pushl SP_ARG2(%esp) /* push the timeout */
  563. leal SEM_Q_HEAD(%ecx),%eax
  564. pushl %eax /* push the &semId->qHead */
  565. call FUNC(windPendQPut) /* block on the semaphore */
  566. addl $8,%esp /* tidy up */
  567. testl %eax,%eax /* if (windPendQPut() != OK) */
  568. jne semQPutFail /*   put failed */
  569. call FUNC(windExit) /* else KERNEL EXIT */
  570. testl %eax,%eax /* if (windExit() != OK) */
  571. jne semWindExitNotOk /*   RESTART */
  572. ret /* done */
  573. .balign 16,0x90
  574. semWindExitNotOk:
  575. cmpl  $1,%eax /* check for RESTART retVal */
  576. je semRestart
  577. ret /* EAX = ERROR */
  578. .balign 16,0x90
  579. semQPutFail:
  580. call FUNC(windExit) /* KERNEL EXIT */
  581. movl $-1,%eax /* return ERROR */
  582. ret /* return to sender */
  583. .balign 16,0x90
  584. semRestart:
  585. pushl SP_ARG2(%esp) /* push the timeout */
  586. movl FUNC(_func_sigTimeoutRecalc),%eax
  587. call *%eax /* recalc the timeout */
  588. addl $4,%esp /* clean up */
  589. movl %eax,SP_ARG2(%esp) /* and store it */
  590. jmp FUNC(semTake) /* start the whole thing over */
  591. /*******************************************************************************
  592. *
  593. * semOTake - VxWorks 4.x semTake
  594. *
  595. * Optimized version of semOTake.  This inserts the necessary argument of
  596. * WAIT_FOREVER for semBTake.
  597. */
  598. .balign 16,0x90
  599. FUNC_LABEL(semOTake)
  600. pushl $-1 /* push WAIT_FOREVER on stack */
  601. movl SP_ARG1+4(%esp),%ecx /* put semId in %ecx */
  602. pushl %ecx /* put semId on stack */
  603. call FUNC(semBTake) /* do semBTake */
  604. addl $8,%esp /* cleanup */
  605. ret
  606. /*******************************************************************************
  607. *
  608. * semClear - VxWorks 4.x semClear
  609. *
  610. * Optimized version of semClear.  This inserts the necessary argument of
  611. * NO_WAIT for semBTake().
  612. */
  613. .balign 16,0x90
  614. FUNC_LABEL(semClear)
  615. pushl $0 /* push NO_WAIT on stack */
  616. movl SP_ARG1+4(%esp),%ecx /* put semId in %ecx */
  617. pushl %ecx /* put semId on stack */
  618. call FUNC(semBTake) /* do semBTake */
  619. addl $8,%esp /* cleanup */
  620. ret
  621. #endif /* !PORTABLE */