linux/arch/i386/lib/semaphore.S
<<
>>
Prefs
   1/*
   2 * i386 semaphore implementation.
   3 *
   4 * (C) Copyright 1999 Linus Torvalds
   5 *
   6 * Portions Copyright 1999 Red Hat, Inc.
   7 *
   8 *      This program is free software; you can redistribute it and/or
   9 *      modify it under the terms of the GNU General Public License
  10 *      as published by the Free Software Foundation; either version
  11 *      2 of the License, or (at your option) any later version.
  12 *
  13 * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org>
  14 */
  15
  16#include <linux/linkage.h>
  17#include <asm/rwlock.h>
  18#include <asm/alternative-asm.i>
  19#include <asm/frame.i>
  20#include <asm/dwarf2.h>
  21
  22/*
  23 * The semaphore operations have a special calling sequence that
  24 * allow us to do a simpler in-line version of them. These routines
  25 * need to convert that sequence back into the C sequence when
  26 * there is contention on the semaphore.
  27 *
  28 * %eax contains the semaphore pointer on entry. Save the C-clobbered
  29 * registers (%eax, %edx and %ecx) except %eax whish is either a return
  30 * value or just clobbered..
  31 */
  32        .section .sched.text
  33ENTRY(__down_failed)
  34        CFI_STARTPROC
  35        FRAME
  36        pushl %edx
  37        CFI_ADJUST_CFA_OFFSET 4
  38        CFI_REL_OFFSET edx,0
  39        pushl %ecx
  40        CFI_ADJUST_CFA_OFFSET 4
  41        CFI_REL_OFFSET ecx,0
  42        call __down
  43        popl %ecx
  44        CFI_ADJUST_CFA_OFFSET -4
  45        CFI_RESTORE ecx
  46        popl %edx
  47        CFI_ADJUST_CFA_OFFSET -4
  48        CFI_RESTORE edx
  49        ENDFRAME
  50        ret
  51        CFI_ENDPROC
  52        END(__down_failed)
  53
  54ENTRY(__down_failed_interruptible)
  55        CFI_STARTPROC
  56        FRAME
  57        pushl %edx
  58        CFI_ADJUST_CFA_OFFSET 4
  59        CFI_REL_OFFSET edx,0
  60        pushl %ecx
  61        CFI_ADJUST_CFA_OFFSET 4
  62        CFI_REL_OFFSET ecx,0
  63        call __down_interruptible
  64        popl %ecx
  65        CFI_ADJUST_CFA_OFFSET -4
  66        CFI_RESTORE ecx
  67        popl %edx
  68        CFI_ADJUST_CFA_OFFSET -4
  69        CFI_RESTORE edx
  70        ENDFRAME
  71        ret
  72        CFI_ENDPROC
  73        END(__down_failed_interruptible)
  74
  75ENTRY(__down_failed_trylock)
  76        CFI_STARTPROC
  77        FRAME
  78        pushl %edx
  79        CFI_ADJUST_CFA_OFFSET 4
  80        CFI_REL_OFFSET edx,0
  81        pushl %ecx
  82        CFI_ADJUST_CFA_OFFSET 4
  83        CFI_REL_OFFSET ecx,0
  84        call __down_trylock
  85        popl %ecx
  86        CFI_ADJUST_CFA_OFFSET -4
  87        CFI_RESTORE ecx
  88        popl %edx
  89        CFI_ADJUST_CFA_OFFSET -4
  90        CFI_RESTORE edx
  91        ENDFRAME
  92        ret
  93        CFI_ENDPROC
  94        END(__down_failed_trylock)
  95
  96ENTRY(__up_wakeup)
  97        CFI_STARTPROC
  98        FRAME
  99        pushl %edx
 100        CFI_ADJUST_CFA_OFFSET 4
 101        CFI_REL_OFFSET edx,0
 102        pushl %ecx
 103        CFI_ADJUST_CFA_OFFSET 4
 104        CFI_REL_OFFSET ecx,0
 105        call __up
 106        popl %ecx
 107        CFI_ADJUST_CFA_OFFSET -4
 108        CFI_RESTORE ecx
 109        popl %edx
 110        CFI_ADJUST_CFA_OFFSET -4
 111        CFI_RESTORE edx
 112        ENDFRAME
 113        ret
 114        CFI_ENDPROC
 115        END(__up_wakeup)
 116
 117/*
 118 * rw spinlock fallbacks
 119 */
 120#ifdef CONFIG_SMP
 121ENTRY(__write_lock_failed)
 122        CFI_STARTPROC simple
 123        FRAME
 1242:      LOCK_PREFIX
 125        addl    $ RW_LOCK_BIAS,(%eax)
 1261:      rep; nop
 127        cmpl    $ RW_LOCK_BIAS,(%eax)
 128        jne     1b
 129        LOCK_PREFIX
 130        subl    $ RW_LOCK_BIAS,(%eax)
 131        jnz     2b
 132        ENDFRAME
 133        ret
 134        CFI_ENDPROC
 135        END(__write_lock_failed)
 136
 137ENTRY(__read_lock_failed)
 138        CFI_STARTPROC
 139        FRAME
 1402:      LOCK_PREFIX
 141        incl    (%eax)
 1421:      rep; nop
 143        cmpl    $1,(%eax)
 144        js      1b
 145        LOCK_PREFIX
 146        decl    (%eax)
 147        js      2b
 148        ENDFRAME
 149        ret
 150        CFI_ENDPROC
 151        END(__read_lock_failed)
 152
 153#endif
 154
 155#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
 156
 157/* Fix up special calling conventions */
 158ENTRY(call_rwsem_down_read_failed)
 159        CFI_STARTPROC
 160        push %ecx
 161        CFI_ADJUST_CFA_OFFSET 4
 162        CFI_REL_OFFSET ecx,0
 163        push %edx
 164        CFI_ADJUST_CFA_OFFSET 4
 165        CFI_REL_OFFSET edx,0
 166        call rwsem_down_read_failed
 167        pop %edx
 168        CFI_ADJUST_CFA_OFFSET -4
 169        pop %ecx
 170        CFI_ADJUST_CFA_OFFSET -4
 171        ret
 172        CFI_ENDPROC
 173        END(call_rwsem_down_read_failed)
 174
 175ENTRY(call_rwsem_down_write_failed)
 176        CFI_STARTPROC
 177        push %ecx
 178        CFI_ADJUST_CFA_OFFSET 4
 179        CFI_REL_OFFSET ecx,0
 180        calll rwsem_down_write_failed
 181        pop %ecx
 182        CFI_ADJUST_CFA_OFFSET -4
 183        ret
 184        CFI_ENDPROC
 185        END(call_rwsem_down_write_failed)
 186
 187ENTRY(call_rwsem_wake)
 188        CFI_STARTPROC
 189        decw %dx    /* do nothing if still outstanding active readers */
 190        jnz 1f
 191        push %ecx
 192        CFI_ADJUST_CFA_OFFSET 4
 193        CFI_REL_OFFSET ecx,0
 194        call rwsem_wake
 195        pop %ecx
 196        CFI_ADJUST_CFA_OFFSET -4
 1971:      ret
 198        CFI_ENDPROC
 199        END(call_rwsem_wake)
 200
 201/* Fix up special calling conventions */
 202ENTRY(call_rwsem_downgrade_wake)
 203        CFI_STARTPROC
 204        push %ecx
 205        CFI_ADJUST_CFA_OFFSET 4
 206        CFI_REL_OFFSET ecx,0
 207        push %edx
 208        CFI_ADJUST_CFA_OFFSET 4
 209        CFI_REL_OFFSET edx,0
 210        call rwsem_downgrade_wake
 211        pop %edx
 212        CFI_ADJUST_CFA_OFFSET -4
 213        pop %ecx
 214        CFI_ADJUST_CFA_OFFSET -4
 215        ret
 216        CFI_ENDPROC
 217        END(call_rwsem_downgrade_wake)
 218
 219#endif
 220
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.