.ad 8
.bm 8
.fm 4
.bt $Copyright by SAP AG, 1994$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$ven76a$
.tt 2 $$$
.tt 3 $$                                       $2001-02-01$
***********************************************************
.nf


    ========== licence begin LGPL
    Copyright (C) 2000 SAP AG

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    ========== licence end

.fo
.nf
.sp
Module  :       lock
=========
.sp
Purpose :       interlock, clearlock
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created :
.sp
.cp 3
Version : 1994-05-17
.sp
.cp 3
Release :      Date : 2001-02-01
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
&undef	PRETTY

&if  $MACH = MX5
;	National Semiconductor Corporation.
;       CTP version 2.1b     -- ven76.s --     Mon Jan 22 13:51:30 1990

	.near
	.endseg
	.program
	.module ven76.s
	.exportp        _e76_getgr11
	.exportp        _e76_interlock
	.exportp        _e76_clearlock
; 	.align 4
_e76_interlock:
	enter    [],0
	sbitiw   0,0(8(fp))
	bfs      L1
	movqd    0,r0
	exit     []
	ret      0
L1:
	movd     1,r0
	exit	 []
	ret	 0
_e76_getgr11:
	ret	 0
_e76_clearlock:
	enter    [],0
	cbitiw   0,0(8(fp))
	bfs      L2
	movqd    0,r0
	exit     []
	ret      0
L2:
	movd     1,r0
	exit	 []
	ret	 0
	.endseg
&endif

&if  $MACH = T35
	.data   0
	.text	0
	.globl  _e76_interlock

_e76_interlock:
	movw    $1,tr0          # compare value is 1
				#
	movw    (pr0),tr1       # access the word to force page-in
				# (do not rely on un-interrupted page-fault)
				#
	bitsw   tr0,(pr0)       # leave as is (=1) return none Z
				# or set to 1 (op2 <-- op2 or op1)
				# and return Z
	bfc     z,p_coll
				# Z = value was one = no success
	movw    $0,pr0          # return 0
	ret
p_coll: movw    $1,pr0          # return 1
	ret
&endif

&if  $MACH IN [ T31 , T32 ]

	global  e76_interlock

e76_interlock:
        link    %fp,&-4
        mov.l   8(%fp),%a0
        nop
        nop
	and.l   &-1,(%a0)       # error in tas in 68020
        tas     (%a0)           # test Semaphore-Byte and Set Bit 1 to 1
        nop
        nop
        bpl     was_0p          # left bit was 0 , now it is 1 , --> locked
	mov.l   &1,%d0          # return false
        unlk    %fp
        rts
was_0p:
	mov.l   &0,%d0          # return true
        unlk    %fp
        rts
 
&endif



&if  $MACH in [ I386 ]
	.file  "ven76a.s"
	.text

#-----------------------------------------------------------------------------
#	void	e76_interlock ( int * addr )
#-----------------------------------------------------------------------------

	.globl  e76_interlock
	.align  4
e76_interlock:
 
	movl    4(%esp),%edx            # get (* addr)

	movl	$1, %eax		# set the intended lock value
	lock				# lock the bus for other processors
					# during the following instruction
	xchg    %eax , (%edx)           # exchange %eax and (* addr)
					# %eax contains the previous (* addr)
	ret	

#-----------------------------------------------------------------------------
#	struct TASK_TYPE * e76_mem_sync ( struct TASK_TYPE * task )
#	Prevent instruction reordering by calling a function.
#-----------------------------------------------------------------------------

	.globl  e76_mem_sync
	.align  4
e76_mem_sync:
 
	movl    4(%esp),%eax            # get (* task)
	ret	
& endif

&if  $MACH = I386_old
	.file  "ven76a.s"
	.text

/-----------------------------------------------------------------------------
/	void	e76_interlock ( addr )
/	int		* addr ;
/-----------------------------------------------------------------------------

	.globl  e76_interlock
	.align  4
e76_interlock:
 
	pushl	%ebp
	movl	%esp,%ebp

	movl    8(%ebp),%eax            / get (* addr)

	lock				/ lock the bus for other processors
					/ during the following instruction
	btsl    $0 , (%eax)             / bit test and set (* addr)
	jc      .L01_lock               / jump, if bit was set

	movl	$0 , %eax		/ set return value for success
	jmp	.L02_lock

.L01_lock:
	movl	$1 , %eax		/ set return value for failure

.L02_lock:
	leave	
	ret	
& endif



&if  $MACH = _IBMR2
		.globl		.e76_dummy[pr]
		.csect		.e76_dummy[pr]
#		This is a dummy to force the module's symbol table non-empty
.e76_dummy:
		l           1,0(3)
		l			0,8(1)
		mtlr		0
		brl
&endif

&if $MACH = PA20W
    .LEVEL 2.0W
    .SPACE $TEXT$,SORT=8
    .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY,SORT=24
e76_hpinterlock
    .PROC
    .CALLINFO 
    .ENTRY
; test+set, and return
     BV    0(rp)
     LDCW  (arg0), ret0
    .EXIT	
    .PROCEND

    .SPACE  $TEXT$
    .SUBSPA $CODE$
    .EXPORT e76_hpinterlock,ENTRY
    .END
&endif

&if $MACH in [ HP9, PA11 ]
    .code
;**************************************************************************
; Test and set routines implemented with the LDCWS instruction
;
; The LDCWS instruction is very similar to a traditional test+set instruction
; with the following exceptions:
;   o Zero means set and One means clear.
;   o Word must be 16 byte aligned
;
; Acheiving 16 byte alignment is awkward in C, so these routines have
; been designed to take a larger unaligned structure and round up to the
; first 16 byte aligned word of the structure.
;
; A reasonable C declaration for this structure could be:
;     typedef  struct { int words[4]; }  latch_t.
;
; On future multiprocessor  machines,  normal load and store instructions could
; be reordered arbitrarily by the hardware.  The stws,ma 0() and ldws,ma 0()
; instructions will force a synchronization of reordered loads and stores.
;************************************************************************ 



; e76_hpinterlock(addr)
;*****************************************************
; e76_hpinterlock is true if we succeeded in acquiring the latch
;****************************************************
    .proc
    .callinfo
    .export e76_hpinterlock
e76_hpinterlock

; test+set, and return
    bv     (rp)
    ldcws  (arg0), ret0
    .procend
&endif

&if $MACH = HP9_OLD

        .SPACE  $TEXT$
        .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=44,CODE_ONLY
e76_interlock
        .PROC
        .CALLINFO CALLER,FRAME=8,ENTRY_GR=3,SAVE_RP
        .ENTRY
        STW     2,-20(0,30)     ;offset 0x0
        STWM    3,64(0,30)      ;offset 0x4
        COPY    26,3    ;offset 0x8
        ADDIL   L'hp9_sema-$global$,27  ;offset 0xc
        LDW     R'hp9_sema-$global$(0,1),26     ;offset 0x14
	LDCWS   0(0,26),28
        COMIBF,=,N      0,28,L$0002     ;offset 0x18
L$0003
        .CALL   ARGW0=GR        ;in=26;
        BL      sleep,2 ;offset 0x1c
        COPY    0,26    ;offset 0x20
L$0001
        ADDIL   L'hp9_sema-$global$,27  ;offset 0x24
        LDW     R'hp9_sema-$global$(0,1),26     ;offset 0x2c
	LDCWS   0(0,26),28
        COMIB,= 0,28,L$0003     ;offset 0x30
        NOP             ;offset 0x34
L$0002
        LDWS    0(0,3),1        ;offset 0x38
        STW     1,-52(0,30)     ;offset 0x3c
        LDI     1,31    ;offset 0x40
        STWS    31,0(0,3)       ;offset 0x44
        ADDIL   L'hp9_sema-$global$,27  ;offset 0x48
        LDW     R'hp9_sema-$global$(0,1),19     ;offset 0x4c
        LDI     1,20    ;offset 0x50
        STWS    20,0(0,19)      ;offset 0x54
        B       L$exit1 ;offset 0x58
        LDW     -52(0,30),28    ;offset 0x5c
L$exit1
        LDW     -84(0,30),2     ;offset 0x60
        BV      0(2)    ;offset 0x64
        .EXIT
        LDWM    -64(0,30),3     ;offset 0x68
        .PROCEND ;in=26;out=28;



        .SPACE  $TEXT$
        .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=44,CODE_ONLY
e76_clearlock
        .PROC
        .CALLINFO CALLER,FRAME=8,ENTRY_GR=3,SAVE_RP
        .ENTRY
        STW     2,-20(0,30)     ;offset 0x6c
        STWM    3,64(0,30)      ;offset 0x70
        COPY    26,3    ;offset 0x74
        ADDIL   L'hp9_sema-$global$,27  ;offset 0x78
        LDW     R'hp9_sema-$global$(0,1),26     ;offset 0x80
	LDCWS   0(0,26),28
        COMIBF,=,N      0,28,L$0005     ;offset 0x84
L$0006
        .CALL   ARGW0=GR        ;in=26;
        BL      sleep,2 ;offset 0x88
        COPY    0,26    ;offset 0x8c
L$0004
        ADDIL   L'hp9_sema-$global$,27  ;offset 0x90
        LDW     R'hp9_sema-$global$(0,1),26     ;offset 0x98
	LDCWS   0(0,26),28
        COMIB,= 0,28,L$0006     ;offset 0x9c
        NOP             ;offset 0xa0
L$0005
        LDWS    0(0,3),21       ;offset 0xa4
        STW     21,-52(0,30)    ;offset 0xa8
        STWS    0,0(0,3)        ;offset 0xac
        ADDIL   L'hp9_sema-$global$,27  ;offset 0xb0
        LDW     R'hp9_sema-$global$(0,1),22     ;offset 0xb4
        LDI     1,1     ;offset 0xb8
        STWS    1,0(0,22)       ;offset 0xbc
        B       L$exit2 ;offset 0xc0
        LDW     -52(0,30),28    ;offset 0xc4
L$exit2
        LDW     -84(0,30),2     ;offset 0xc8
        BV      0(2)    ;offset 0xcc
        .EXIT
        LDWM    -64(0,30),3     ;offset 0xd0
        .PROCEND ;in=26;out=28;



        .SPACE  $TEXT$
        .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
        .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=44,CODE_ONLY
        .SUBSPA $UNWIND$,QUAD=0,ALIGN=8,ACCESS=44
        .SUBSPA $CODE$
        .SUBSPA $CODE$
        .SPACE  $PRIVATE$
        .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
$THIS_DATA$

        .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO
$THIS_BSS$

        .IMPORT $global$,DATA
        .IMPORT hp9_sema,DATA
        .SPACE  $TEXT$
        .SUBSPA $CODE$
	.EXPORT e76_interlock,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
        .IMPORT ttt,CODE
        .IMPORT sleep,CODE
        .SUBSPA $CODE$
	.EXPORT e76_clearlock,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
        .END

        .SPACE  $TEXT$
        .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=44,CODE_ONLY
ttt
        .PROC
        .CALLINFO CALLER,FRAME=8
	LDCWS   0(0,26),28
        BV      0(2)    ;offset 0x1c
        .PROCEND ;in=26;out=28;


        .SPACE  $TEXT$
        .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
        .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=44,CODE_ONLY
        .SUBSPA $UNWIND$,QUAD=0,ALIGN=8,ACCESS=44
        .SUBSPA $CODE$
        .SPACE  $PRIVATE$
        .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
$THIS_DATA$

        .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO
$THIS_BSS$

        .SPACE  $TEXT$
        .SUBSPA $CODE$
        .EXPORT ttt,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
        .END

&endif

&if $MACH = SUN

	.seg	"text"			! [internal]
	.proc	4
&	if $OSSPEC = SVR4
	.global	e76_interlock
e76_interlock:
&	else
	.global	_e76_interlock
_e76_interlock:
&	endif
	mov	1,%o1
	swap	[%o0],%o1
	tst	%o1
	bne,a	e76_inter_end
	mov	1,%o0
	mov	0,%o0
e76_inter_end:
	retl
	nop				! [internal]
!#	.proc	4
!#	.global	_e76_clearlock
!#_e76_clearlock:
!#	mov	0,%o1
!#	swap	[%o0],%o1
!#	tst	%o1
!#	bne,a	e76_clear_end
!#	mov	1,%o0
!#	mov	0,%o0
!#e76_clear_end:
!#	retl
!#	nop				! [internal]
!#	.seg	"data"			! [internal]

&endif

&if  $MACH = ALPHA and $OSSPEC = OSF1
	.file	2 "ven76a.s"
	.text	
	.align	4
/*
 * e76_interlock ( int *addr )
 * return 0 if *addr can be changed from 0 to 1
 */
	.globl	e76_interlock
	.ent	e76_interlock
e76_interlock:
	ldgp    $gp, 0($27)
	.frame  $sp, 0, $26, 0
	.prologue       1
	ldl_l	$1, 0($16)	/* get *addr */
	blbs	$1, e76_tas_already_set
	or	$1, 1, $2	/* 0 becomes 1 */
	stl_c	$2, 0($16)	/* try to write to *addr */
	beq	$2, e76_tas_no_set
	mb			/* memory barrier #1: critical section begins */
	bis     $31, $31, $0	/* set: return 0 */
	ret	$31, ($26), 1	/* return to caller */
e76_tas_already_set:
e76_tas_no_set:
	ldil    $0, 1		/* not set: return 1 */
	ret	$31, ($26), 1	/* return to caller */
	.end	e76_interlock
/*
 * e76_clearlock ( int *addr )
 * set *addr to 0, return 0
 */
	.globl	e76_clearlock
	.ent	e76_clearlock 2
e76_clearlock:
	ldgp	$gp, 0($27)
	.frame	$sp, 0, $26, 0
	.prologue	1
	mb			/* memory barrier #2: critical section ends */
	stl	$31, 0($16)
	bis	$31, $31, $0
	ret	$31, ($26), 1	/* return 0 */
	.end	e76_clearlock
/* 
 * struct TASK_TYPE * e76_mem_sync ( struct TASK_TYPE * task )
 * call mb, return task
 */
	.globl  e76_mem_sync
        .ent    e76_mem_sync
e76_mem_sync:
        ldgp    $gp, 0($27)	/* global ptr gets addr of this function */
        .frame  $sp, 0, $26, 0
        .prologue       1
        mb			/* memory barrier */
        bis     $16, $16, $0	/* arg1 to return reg */
        mb			/* memory barrier */
        ret     $31, ($26), 1	/* return task */
        .end    e76_mem_sync
&endif

.CM *-END-* code ----------------------------------------
.sp 2 
***********************************************************
*-PRETTY-*  statements    :
*-PRETTY-*  lines of code :
*-PRETTY-*  lines in file :
.pa 
