📄 semmalib.s
字号:
/* semMALib.s - i80x86 internal VxWorks mutex semaphore assembly library *//* Copyright 1984-1991 Wind River Systems, Inc. */ .data .globl _copyright_wind_river .long _copyright_wind_river/*modification history--------------------01c,29jul96,sbs Made windview conditionally compile.01b,08aug94,hdn added support for WindView.01a,02jun93,hdn extracted from semALib.s*//*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"#ifndef PORTABLE /* globals */ .globl _semMGive /* optimized mutex semaphore give */ .globl _semMTake /* optimized mutex semaphore take */ .text .align 4/********************************************************************************* semIsInvalid - unlock interupts and call semInvalid ().*/semIsInvalidUnlock: sti /* UNLOCK INTERRUPTS */semIsInvalid: jmp _semInvalid /* let C rtn do work and ret *//********************************************************************************* semMGive - optimized give of a counting semaphore** STATUS semMGive* (* SEM_ID semId /@ semaphore id to give @/* )*/ .align 4,0x90semMIntRestrict: jmp _semIntRestrict /* let C do the work */ .align 4,0x90semMRecurse: decw SEM_RECURSE(%ecx) /* decrement recurse count */ ret .align 4,0x90_semMGive: /* %ecx = semId! %eax = 0! */ movl _taskIdCurrent,%edx /* taskIdCurrent into %edx */ cmpl $0,_intCnt /* restrict isr use */ jne semMIntRestrict /* intCnt > 0 */ cmpl $_semClass,(%ecx) /* check validity */#ifdef WV_INSTRUMENTATION je objOkMGive /* windview - check the validity of instrumented class */ cmpl $_semInstClass,(%ecx) /* check validity */ jne semIsInvalid /* semaphore id error */objOkMGive:#else jne semIsInvalid /* semaphore id error */#endif /* WV_INSTRUMENTATION */ cmpl SEM_STATE(%ecx),%edx /* taskIdCurrent is owner? */ jne semIsInvalid /* SEM_INVALID_OPERATION */ cmpw $0,SEM_RECURSE(%ecx) /* if recurse count > 0 */ jne semMRecurse /* handle recursion */semMInvCheck: testb $0x8,SEM_OPTIONS(%ecx) /* SEM_INVERSION_SAFE? */ je semMQLock /* if not, test semQ */ decl WIND_TCB_MUTEX_CNT(%edx) /* decrement mutex count */ jne semMQLock /* if nonzero, test semQ */ cli /* LOCK INTERRUPTS */ movl WIND_TCB_PRIORITY(%edx),%eax /* put priority in %eax */ subl WIND_TCB_PRI_NORMAL(%edx),%eax /* subtract normal priority */ je semMStateSet /* if same, test semQ */ movl $4,%eax /* or in PRIORITY_RESORT */ jmp semMStateSet /* now test mutex sem queue */ .align 4,0x90semMQLock: cli /* LOCK INTERRUPTS */semMStateSet: pushl SEM_Q_HEAD(%ecx) /* update semaphore state */ popl SEM_STATE(%ecx) cmpl $0,SEM_STATE(%ecx) je semMDelSafe /* anyone need to be got */ incl %eax /* set SEM_Q_GET */semMDelSafe: testb $0x4,SEM_OPTIONS(%ecx) /* SEM_DELETE_SAFE? */ je semMShortCut /* check for short cut */ decl WIND_TCB_SAFE_CNT(%edx) /* decrement safety count */ jne semMShortCut /* check for short cut */ cmpl $0,WIND_TCB_SAFETY_Q_HEAD(%edx) /* check for pended deleters */ je semMShortCut /* check for short cut */ addl $2,%eax /* set SAFETY_Q_FLUSH */semMShortCut: cmpl $0,%eax /* any work for kernel level? */ jne semMKernWork /* enter kernel if any work */ sti /* UNLOCK INTERRUPTS */ ret /* %eax is still 0 for OK */ .align 4,0x90semMKernWork: movl $1,_kernelState /* KERNEL ENTER */ sti /* UNLOCK INTERRUPTS */ movl %eax,_semMGiveKernWork /* setup work for semMGiveKern*/ jmp _semMGiveKern /* finish semMGive in C *//********************************************************************************* semMTake - optimized take of a mutex semaphore** STATUS semMTake* (* SEM_ID semId /@ semaphore id to give @/* )*/ .align 4,0x90_semMTake: /* %edx = semId! */ movl _taskIdCurrent,%edx /* taskIdCurrent into %edx */ cli /* LOCK INTERRUPTS */ cmpl $_semClass,(%ecx) /* check validity */#ifdef WV_INSTRUMENTATION je objOkMTake /* windview - check the validity of instrumented class */ cmpl $_semInstClass,(%ecx) /* check validity */ jne semIsInvalidUnlock /* invalid semaphore */objOkMTake:#else jne semIsInvalidUnlock /* invalid semaphore */#endif /* WV_INSTRUMENTATION */ movl SEM_STATE(%ecx),%eax /* test for owner */ cmpl $0,%eax jne semMEmpty /* sem is owned, is it ours? */ movl %edx,SEM_STATE(%ecx) /* we now own semaphore */ testb $0x4,SEM_OPTIONS(%ecx) /* SEM_DELETE_SAFE? */ je semMPriCheck /* semMPriCheck */ incl WIND_TCB_SAFE_CNT(%edx) /* bump safety count */semMPriCheck: testb $0x8,SEM_OPTIONS(%ecx) /* SEM_INVERSION_SAFE? */ je semMDone /* if not, skip increment */ incl WIND_TCB_MUTEX_CNT(%edx) /* bump priority mutex count */semMDone: sti /* UNLOCK INTERRUPTS */ ret /* %eax is still 0 for OK */ .align 4,0x90semMEmpty: subl %edx,%eax /* recursive take */ jne semMQUnlockPut /* if not, block */ incw SEM_RECURSE(%ecx) /* increment recurse count */ sti /* UNLOCK INTERRUPTS */ ret /* %eax is still 0 for OK */ .align 4,0x90semMQUnlockPut: movl $1,_kernelState /* KERNEL ENTER */ sti /* UNLOCK INTERRUPTS */ pushl SP_ARG2(%esp) /* push the timeout */ pushl %ecx /* push the semId */ call _semMPendQPut /* do as much in C as possible*/ addl $8,%esp /* clean up */ cmpl $0,%eax /* test return value */ jne semMFail /* if !OK, exit kernel, ERROR */ .align 4,0x90semMQPendQOk: call _windExit /* KERNEL EXIT */ cmpl $0,%eax /* test the return value */ jg semMRestart /* is it a RESTART ? */ ret /* finished, OK or TIMEOUT */ .align 4,0x90semMRestart: pushl SP_ARG2(%esp) /* push the timeout */ movl __func_sigTimeoutRecalc,%eax /* address of recalc routine */ call *%eax /* recalc the timeout */ addl $4,%esp /* clean up */ movl %eax,SP_ARG2(%esp) /* restore the timeout */ jmp _semTake /* start the whole thing over */ .align 4,0x90semMFail: call _windExit /* KERNEL EXIT */ movl $-1,%eax /* return ERROR */ ret /* failed */#endif /* !PORTABLE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -