📄 semalib.s
字号:
/* semALib.s - i80x86 internal VxWorks binary semaphore assembly library *//* Copyright 1984-1993 Wind River Systems, Inc. */ .data .globl _copyright_wind_river .long _copyright_wind_river/*modification history--------------------01i,30apr98,cjtc bug fixes in semaphore instrumentation01h,28apr98,pr fixed problem with registers in WV code.01g,16apr98,pr cleanup.01f,17feb98,pr added WindView 2.0 code.01f,24jun97,sub fixed semTakeGlobal and semGiveGlobal for VxMP - SPR # 883301e,29jul96,sbs Made windview conditionally compile.01d,08aug94,hdn added support for WindView.01c,02jun93,hdn split into sem[CM]ALib.s to increase modularity. added shared memory semaphores support. added signal restart. updated to 5.1 - fixed #else and #endif - changed ASMLANGUAGE to _ASMLANGUAGE - changed copyright notice01b,13oct92,hdn debugged.01a,07apr92,hdn written based on TRON version.*//*DESCRIPTIONThis module contains internals to the VxWorks kernel.These routines have been coded in assembler because they are optimized forperformance.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"#include "private/taskLibP.h"#include "private/semLibP.h"#include "private/eventP.h" #ifndef PORTABLE /* globals */ .globl _semGive /* optimized semGive demultiplexer */ .globl _semTake /* optimized semTake demultiplexer */ .globl _semBGive /* optimized binary semaphore give */ .globl _semBTake /* optimized binary semaphore take */ .globl _semQGet /* semaphore queue get routine */ .globl _semQPut /* semaphore queue put routine */ .globl _semOTake /* optimized old semaphore take */ .globl _semClear /* optimized old semaphore semClear */ .text .align 4/********************************************************************************* semGiveKern - add give routine to work queue**/semGiveKern: jmp _semGiveDefer /* let C rtn defer work and ret *//********************************************************************************* semGive - give a semaphore***STATUS semGive (semId)* SEM_ID semId; /* semaphore id to give **/ .align 4,0x90_semGive: movl SP_ARG1(%esp),%ecx /* semId goes into %ecx */ testl $1,%ecx /* is it a global semId */ jne semGiveGlobal /* if LSB is 1, its a global sem */#ifdef WV_INSTRUMENTATION /* windview instrumentation - BEGIN * semGive: object status class */ cmpl $0,_evtAction /* is WindView on? */ je noSemGiveEvt cmpl $_semClass,(%ecx) /* check validity */ je objOkGive cmpl $_semInstClass,(%ecx) /* check validity */ jne noSemGiveEvt /* invalid semaphore */objOkGive: movl $ WV_CLASS_3_ON,%eax andl _wvEvtClass,%eax /* is event collection on? */ cmpl $ WV_CLASS_3_ON,%eax /* is event collection on? */ jne trgCheckSemGive pushl %eax pushl %ecx /* semId */ pushl %edx /* is this semaphore object instrumented? */ movl (%ecx),%eax /* %ecx - semId */ cmpl $0,SEM_INST_RTN(%eax) /* event routine attached? */ je trgNoSemGive /* log event for this object */ pushl $0 pushl $0 movl $0,%edx movw SEM_RECURSE(%ecx),%edx /* recursively called */ pushl %edx movl SEM_STATE(%ecx),%edx /* state/count/owner */ pushl %edx pushl %ecx /* semId */ pushl $ 3 /* number of paramters */ pushl $ EVENT_SEMGIVE /* EVENT_SEMGIVE, event id */ movl SEM_INST_RTN(%eax),%edx /* get logging routine */ call *%edx /* call routine */ addl $28,%esptrgNoSemGive: popl %edx popl %ecx /* semId */ popl %eaxtrgCheckSemGive: movl $ TRG_CLASS_3,%eax orl $ TRG_ON,%eax cmpl _trgEvtClass,%eax /* any trigger? */ jne noSemGiveEvt movl __func_trgCheck,%eax /* triggering routine */ cmpl $0,%eax je noSemGiveEvt pushl %ecx /* semId */ pushl %edx pushl $ 0 /* 0 */ pushl $ 0 /* 0 */ movl $0,%edx movw SEM_RECURSE(%ecx),%edx /* recursively called */ pushl %edx movl SEM_STATE(%ecx),%edx /* state/count/owner */ pushl %edx pushl %ecx /* semId */ pushl %ecx /* objId */ pushl $ TRG_CLASS3_INDEX /* TRG_CLASS3_INDEX */ pushl $ EVENT_SEMGIVE /* EVENT_SEMGIVE, event id */ call *%eax /* call triggering routine */ addl $32,%esp popl %edx popl %ecx /* semId */noSemGiveEvt: /* windview instrumentation - END */#endif /* WV_INSTRUMENTATION */ movl _kernelState,%eax /* are we in kernel state? */ cmpl $0,%eax jne semGiveKern /* %eax = 0 if we are not */ movb SEM_TYPE(%ecx),%dl /* put the sem class into %edx */ andl $7,%edx /* mask %edx to MAX_SEM_TYPE value */ jne semGiveNotBinary /* optimize for BINARY if %edx == 0 */ /* BINARY SEMAPHORE OPTIMIZATION */_semBGive: /* %ecx = semId! %eax = 0! */ cli /* LOCK INTERRUPTS */ cmpl $_semClass,(%ecx) /* check validity *//* FIXME-PR: if this is going to be part of the kernel permanently, it should be rearranged. It does an extra instruction that is not needed. */#ifdef WV_INSTRUMENTATION je objOkBGive /* windview - check the validity of instrumented class */ cmpl $_semInstClass,(%ecx) /* instrumented class check */ jne semIsInvalidUnlock /* semaphore id error */objOkBGive:#else jne semIsInvalidUnlock /* invalid semaphore */#endif /* WV_INSTRUMENTATION */ movl SEM_Q_HEAD(%ecx),%edx movl %edx,SEM_STATE(%ecx) cmpl $0,%edx jne _semQGet /* if not empty, get from q */ sti /* UNLOCK INTERRUPTS */ ret /* %eax is still 0 for OK */ .align 4,0x90semGiveNotBinary: /* call semGive indirectly via semGiveTbl. Note that the index could * equal zero after it is masked. semBGive is the zeroeth element * of the table, but for it to function correctly in the optimized * version above, we must be certain not to clobber a0. Note, also * that old semaphores will also call semBGive above. */ movl _semGiveTbl(,%edx,4),%edx jmp *%edx /* invoke give rtn, it will do ret */ .align 4,0x90semGiveGlobal: addl _smObjPoolMinusOne,%ecx /* convert id to local address */ movb 7(%ecx),%dl /* get semaphore type in %dl */ /* offset 7 is used as the type * is stored in network order */ andl $7,%edx /* mask %edx to MAX_SEM_TYPE */ movl _semGiveTbl(,%edx,4),%edx /* %edx is appropriate give rtn. */ pushl %ecx /* push converted semId */ call *%edx /* call appropriate give rtn. */ addl $4,%esp /* clean up */ ret/********************************************************************************* semIsInvalid - unlock interupts and call semInvalid ().*/ .align 4,0x90semIsInvalidUnlock: sti /* UNLOCK INTERRUPTS */semIsInvalid: jmp _semInvalid /* let C rtn do work and ret *//********************************************************************************* semTake - take a semaphore** STATUS semTake (semId, timeout)* SEM_ID semId; /* semaphore id to give ** ULONG timeout; /* timeout in ticks **/ .align 4,0x90_semTake: movl SP_ARG1(%esp),%ecx /* semId goes into %ecx */ testl $1,%ecx /* is it a global semId */ jne semTakeGlobal /* if LSB is 1, its a global sem */#ifdef WV_INSTRUMENTATION /* windview instrumentation - BEGIN * semTake: object status class */ cmpl $0,_evtAction /* is WindView on? */ je noSemTakeEvt cmpl $_semClass,(%ecx) /* check validity */ je objOkTake cmpl $_semInstClass,(%ecx) /* check validity */ jne noSemTakeEvt /* invalid semaphore */objOkTake: movl $ WV_CLASS_3_ON,%eax andl _wvEvtClass,%eax /* is event collection on? */ cmpl $ WV_CLASS_3_ON,%eax /* is event collection on? */ jne trgCheckSemTake pushl %eax pushl %ecx /* semId */ pushl %edx /* is this semaphore object instrumented? */ movl (%ecx),%eax /* %ecx - semId */ cmpl $0,SEM_INST_RTN(%eax) /* event routine attached? */ je trgNoSemTake /* log event for this object */ pushl $0 pushl $0 movl $0,%edx movw SEM_RECURSE(%ecx),%edx /* recursively called */ pushl %edx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -