2011-07-19 16:00:19 +04:00
/ *
* x8 6 s e m a p h o r e i m p l e m e n t a t i o n .
*
* ( C) C o p y r i g h t 1 9 9 9 L i n u s T o r v a l d s
*
* Portions C o p y r i g h t 1 9 9 9 R e d H a t , I n c .
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or
* modify i t u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e
* as p u b l i s h e d b y t h e F r e e S o f t w a r e F o u n d a t i o n ; either version
* 2 of t h e L i c e n s e , o r ( a t y o u r o p t i o n ) a n y l a t e r v e r s i o n .
*
* rw s e m a p h o r e s i m p l e m e n t e d N o v e m b e r 1 9 9 9 b y B e n j a m i n L a H a i s e < b c r l @kvack.org>
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a l t e r n a t i v e - a s m . h >
# include < a s m / d w a r f2 . h >
# define _ _ A S M _ H A L F _ R E G ( r e g ) _ _ A S M _ S E L ( r e g , e ## r e g )
# define _ _ A S M _ H A L F _ S I Z E ( i n s t ) _ _ A S M _ S E L ( i n s t ## w , i n s t # # l )
# ifdef C O N F I G _ X 8 6 _ 3 2
/ *
* The s e m a p h o r e o p e r a t i o n s h a v e a s p e c i a l c a l l i n g s e q u e n c e t h a t
* allow u s t o d o a s i m p l e r i n - l i n e v e r s i o n o f t h e m . T h e s e r o u t i n e s
* need t o c o n v e r t t h a t s e q u e n c e b a c k i n t o t h e C s e q u e n c e w h e n
* there i s c o n t e n t i o n o n t h e s e m a p h o r e .
*
* % eax c o n t a i n s t h e s e m a p h o r e p o i n t e r o n e n t r y . S a v e t h e C - c l o b b e r e d
* registers ( % e a x , % e d x a n d % e c x ) e x c e p t % e a x w h i s h i s e i t h e r a r e t u r n
* value o r j u s t c l o b b e r e d . .
* /
# define s a v e _ c o m m o n _ r e g s \
pushl_ c f i % e c x ; CFI_REL_OFFSET ecx, 0
# define r e s t o r e _ c o m m o n _ r e g s \
popl_ c f i % e c x ; CFI_RESTORE ecx
/* Avoid uglifying the argument copying x86-64 needs to do. */
.macro movq src, d s t
.endm
# else
2010-01-13 05:16:42 +03:00
/ *
* x8 6 - 6 4 r w s e m w r a p p e r s
*
* This i n t e r f a c e s t h e i n l i n e a s m c o d e t o t h e s l o w - p a t h
* C r o u t i n e s . W e n e e d t o s a v e t h e c a l l - c l o b b e r e d r e g s
* that t h e a s m d o e s n o t m a r k a s c l o b b e r e d , a n d m o v e t h e
* argument f r o m % r a x t o % r d i .
*
* NOTE! W e d o n ' t n e e d t o s a v e % r a x , b e c a u s e t h e f u n c t i o n s
* will a l w a y s r e t u r n t h e s e m a p h o r e p o i n t e r i n % r a x ( w h i c h
* is a l s o t h e i n p u t a r g u m e n t t o t h e s e h e l p e r s )
*
* The f o l l o w i n g c a n c l o b b e r % r d x b e c a u s e t h e a s m c l o b b e r s i t :
* call_ r w s e m _ d o w n _ w r i t e _ f a i l e d
* call_ r w s e m _ w a k e
* but % r d i , % r s i , % r c x , % r8 - r11 a l w a y s n e e d s a v i n g .
* /
# define s a v e _ c o m m o n _ r e g s \
2011-02-28 18:31:59 +03:00
pushq_ c f i % r d i ; CFI_REL_OFFSET rdi, 0; \
pushq_ c f i % r s i ; CFI_REL_OFFSET rsi, 0; \
pushq_ c f i % r c x ; CFI_REL_OFFSET rcx, 0; \
pushq_ c f i % r8 ; CFI_REL_OFFSET r8, 0; \
pushq_ c f i % r9 ; CFI_REL_OFFSET r9, 0; \
pushq_ c f i % r10 ; CFI_REL_OFFSET r10, 0; \
pushq_ c f i % r11 ; CFI_REL_OFFSET r11, 0
2010-01-13 05:16:42 +03:00
# define r e s t o r e _ c o m m o n _ r e g s \
2011-02-28 18:31:59 +03:00
popq_ c f i % r11 ; CFI_RESTORE r11; \
popq_ c f i % r10 ; CFI_RESTORE r10; \
popq_ c f i % r9 ; CFI_RESTORE r9; \
popq_ c f i % r8 ; CFI_RESTORE r8; \
popq_ c f i % r c x ; CFI_RESTORE rcx; \
popq_ c f i % r s i ; CFI_RESTORE rsi; \
popq_ c f i % r d i ; CFI_RESTORE rdi
2010-01-13 05:16:42 +03:00
2011-07-19 16:00:19 +04:00
# endif
2010-01-13 05:16:42 +03:00
/* Fix up special calling conventions */
ENTRY( c a l l _ r w s e m _ d o w n _ r e a d _ f a i l e d )
2011-02-28 18:31:59 +03:00
CFI_ S T A R T P R O C
2010-01-13 05:16:42 +03:00
save_ c o m m o n _ r e g s
2011-07-19 16:00:19 +04:00
_ _ ASM_ S I Z E ( p u s h ,_ c f i ) % _ _ A S M _ R E G ( d x )
CFI_ R E L _ O F F S E T _ _ A S M _ R E G ( d x ) , 0
2010-01-13 05:16:42 +03:00
movq % r a x ,% r d i
call r w s e m _ d o w n _ r e a d _ f a i l e d
2011-07-19 16:00:19 +04:00
_ _ ASM_ S I Z E ( p o p ,_ c f i ) % _ _ A S M _ R E G ( d x )
CFI_ R E S T O R E _ _ A S M _ R E G ( d x )
2010-01-13 05:16:42 +03:00
restore_ c o m m o n _ r e g s
ret
2011-02-28 18:31:59 +03:00
CFI_ E N D P R O C
ENDPROC( c a l l _ r w s e m _ d o w n _ r e a d _ f a i l e d )
2010-01-13 05:16:42 +03:00
ENTRY( c a l l _ r w s e m _ d o w n _ w r i t e _ f a i l e d )
2011-02-28 18:31:59 +03:00
CFI_ S T A R T P R O C
2010-01-13 05:16:42 +03:00
save_ c o m m o n _ r e g s
movq % r a x ,% r d i
call r w s e m _ d o w n _ w r i t e _ f a i l e d
restore_ c o m m o n _ r e g s
ret
2011-02-28 18:31:59 +03:00
CFI_ E N D P R O C
ENDPROC( c a l l _ r w s e m _ d o w n _ w r i t e _ f a i l e d )
2010-01-13 05:16:42 +03:00
ENTRY( c a l l _ r w s e m _ w a k e )
2011-02-28 18:31:59 +03:00
CFI_ S T A R T P R O C
2011-07-19 16:00:19 +04:00
/* do nothing if still outstanding active readers */
_ _ ASM_ H A L F _ S I Z E ( d e c ) % _ _ A S M _ H A L F _ R E G ( d x )
2010-01-13 05:16:42 +03:00
jnz 1 f
save_ c o m m o n _ r e g s
movq % r a x ,% r d i
call r w s e m _ w a k e
restore_ c o m m o n _ r e g s
1 : ret
2011-02-28 18:31:59 +03:00
CFI_ E N D P R O C
ENDPROC( c a l l _ r w s e m _ w a k e )
2010-01-13 05:16:42 +03:00
ENTRY( c a l l _ r w s e m _ d o w n g r a d e _ w a k e )
2011-02-28 18:31:59 +03:00
CFI_ S T A R T P R O C
2010-01-13 05:16:42 +03:00
save_ c o m m o n _ r e g s
2011-07-19 16:00:19 +04:00
_ _ ASM_ S I Z E ( p u s h ,_ c f i ) % _ _ A S M _ R E G ( d x )
CFI_ R E L _ O F F S E T _ _ A S M _ R E G ( d x ) , 0
2010-01-13 05:16:42 +03:00
movq % r a x ,% r d i
call r w s e m _ d o w n g r a d e _ w a k e
2011-07-19 16:00:19 +04:00
_ _ ASM_ S I Z E ( p o p ,_ c f i ) % _ _ A S M _ R E G ( d x )
CFI_ R E S T O R E _ _ A S M _ R E G ( d x )
2010-01-13 05:16:42 +03:00
restore_ c o m m o n _ r e g s
ret
2011-02-28 18:31:59 +03:00
CFI_ E N D P R O C
ENDPROC( c a l l _ r w s e m _ d o w n g r a d e _ w a k e )