📄 workqalib.s
字号:
/* workQALib.s - i80x86 internal VxWorks kernel work queue assembly library *//* Copyright 1984-1993 Wind River Systems, Inc. */ .data .globl _copyright_wind_river .long _copyright_wind_river/*modification history--------------------01g,25feb99,nps remove obsolete scrPad reference.01f,17feb98,pr deleted Windview code (no more needed).01e,29jul96,sbs Made windview conditionally compile.01d,08aug94,hdn added support for WindView.01c,17nov93,hdn fixed a bug: changed movb to movzbl.01b,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/workQLibP.h"#include "private/eventP.h"#ifndef PORTABLE /* globals */ .globl _workQAdd0 /* add function to workQ */ .globl _workQAdd1 /* add function and 1 arg to workQ */ .globl _workQAdd2 /* add function and 2 args to workQ */ .globl _workQDoWork /* do all queued work in a workQ */ .text .align 4/********************************************************************************* workQOverflow - work queue has overflowed so call workQPanic ()** NOMANUAL*/ workQOverflow: /* leave interrupts locked */ call _workQPanic /* panic and never return *//********************************************************************************* workQAdd0 - add a function with no argument to the work queue** NOMANUAL* void workQAdd0 (func)* FUNCPTR func; /* function to invoke **/ .align 4,0x90_workQAdd0: cli /* LOCK INTERRUPTS */ movzbl _workQWriteIx,%eax /* get write index into %eax */ movl %eax,%ecx addb $4,%al /* advance write index */ cmpb _workQReadIx,%al /* overflow? */ je workQOverflow /* panic if overflowed */ movb %al,_workQWriteIx /* update write index */ sti /* UNLOCK INTERRUPTS */ movl $0,_workQIsEmpty /* work queue isn't empty */ leal _pJobPool(,%ecx,4),%edx /* get a start of an entry */ movl SP_ARG1(%esp),%eax /* move it to pool */ movl %eax,JOB_FUNCPTR(%edx) ret /* we're done *//********************************************************************************* workQAdd1 - add a function with one argument to the work queue** NOMANUAL* void workQAdd1 (func, arg1)* FUNCPTR func; /* function to invoke ** int arg1; /* parameter one to function **/ .align 4,0x90_workQAdd1: cli /* LOCK INTERRUPTS */ movzbl _workQWriteIx,%eax /* get write index into %eax */ movl %eax,%ecx addb $4,%al /* advance write index */ cmpb _workQReadIx,%al /* overflow? */ je workQOverflow /* panic if overflowed */ movb %al,_workQWriteIx /* update write index */ sti /* UNLOCK INTERRUPTS */ movl $0,_workQIsEmpty /* work queue isn't empty */ leal _pJobPool(,%ecx,4),%edx /* get the start of an entry */ movl SP_ARG1(%esp),%eax /* move the function to pool */ movl %eax,JOB_FUNCPTR(%edx) movl SP_ARG2(%esp),%eax /* move the argument to pool */ movl %eax,JOB_ARG1(%edx) ret /* we're done *//********************************************************************************* workQAdd2 - add a function with two arguments to the work queue** NOMANUAL* void workQAdd2 (func, arg1, arg2)* FUNCPTR func; /* function to invoke ** int arg1; /* parameter one to function ** int arg2; /* parameter two to function **/ .align 4,0x90_workQAdd2: cli /* LOCK INTERRUPTS */ movzbl _workQWriteIx,%eax /* get write index into %eax */ movl %eax,%ecx addb $4,%al /* advance write index */ cmpb _workQReadIx,%al /* overflow? */ je workQOverflow /* panic if overflowed */ movb %al,_workQWriteIx /* update write index */ sti /* UNLOCK INTERRUPTS */ movl $0,_workQIsEmpty /* work queue isn't empty */ leal _pJobPool(,%ecx,4),%edx /* get the start of an entry */ movl SP_ARG1(%esp),%eax /* move the function to pool */ movl %eax,JOB_FUNCPTR(%edx) movl SP_ARG2(%esp),%eax /* move 1st argument to pool */ movl %eax,JOB_ARG1(%edx) movl SP_ARG3(%esp),%eax /* move 2nd argument to pool */ movl %eax,JOB_ARG2(%edx) ret /* we're done */ /********************************************************************************* workQDoWork - perform all the work queued in the kernel work queue** This routine empties all the deferred work in the work queue. The global* variable errno is saved restored, so the work will not clobber it.* The work routines may be C code, and thus clobber the volatile registers* %e[adc]x. This routine avoids using these registers.** NOMANUAL* void workQDoWork ()*/ .align 4,0x90_workQDoWork: pushl _errno /* push _errno */ movzbl _workQReadIx,%eax /* load read index */ cmpb _workQWriteIx,%al /* if readIndex != writeIndex */ je workQNoMoreWork /* more work to be done */workQMoreWork: sall $2,%eax leal _pJobPool(%eax),%edx addb $4,_workQReadIx /* increment readIndex */ pushl JOB_ARG2(%edx) /* push arg2 */ pushl JOB_ARG1(%edx) /* push arg1 */ movl _pJobPool(%eax),%eax call *%eax /* %eax the work routine */ addl $8,%esp /* clean up stack */ movl $1,_workQIsEmpty /* set boolean before test! */ movzbl _workQReadIx,%eax /* load the new read index */ cmpb _workQWriteIx,%al /* if readIndex != writeIndex */ jne workQMoreWork /* more work to be done */workQNoMoreWork: pop _errno /* pop _errno */ ret /* return to caller */#endif /* !PORTABLE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -