linux/lib/rwsem-spinlock.c
<<
>>
Prefs
   1/* rwsem-spinlock.c: R/W semaphores: contention handling functions for
   2 * generic spinlock implementation
   3 *
   4 * Copyright (c) 2001   David Howells (dhowells@redhat.com).
   5 * - Derived partially from idea by Andrea Arcangeli <andrea@suse.de>
   6 * - Derived also from comments by Linus
   7 */
   8#include <linux/rwsem.h>
   9#include <linux/sched.h>
  10#include <linux/export.h>
  11
  12struct rwsem_waiter {
  13        struct list_head list;
  14        struct task_struct *task;
  15        unsigned int flags;
  16#define RWSEM_WAITING_FOR_READ  0x00000001
  17#define RWSEM_WAITING_FOR_WRITE 0x00000002
  18};
  19
  20int rwsem_is_locked(struct rw_semaphore *sem)
  21{
  22        int ret = 1;
  23        unsigned long flags;
  24
  25        if (raw_spin_trylock_irqsave(&sem->wait_lock, flags)) {
  26                ret = (sem->activity != 0);
  27                raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
  28        }
  29        return ret;
  30}
  31EXPORT_SYMBOL(rwsem_is_locked);
  32
  33/*
  34 * initialise the semaphore
  35 */
  36void __init_rwsem(struct rw_semaphore *sem, const char *name,
  37                  struct lock_class_key *key)
  38{
  39#ifdef CONFIG_DEBUG_LOCK_ALLOC
  40        /*
  41         * Make sure we are not reinitializing a held semaphore:
  42         */
  43        debug_check_no_locks_freed((void *)sem, sizeof(*sem));
  44        lockdep_init_map(&sem->dep_map, name, key, 0);
  45#endif
  46        sem->activity = 0;
  47        raw_spin_lock_init(&sem->wait_lock);
  48        INIT_LIST_HEAD(&sem->wait_list);
  49}
  50EXPORT_SYMBOL(__init_rwsemlist" class="sref">wait_list);51" id="L51" class="line" name="L416>  415/a>
  
 *
 * in-f (< armmeeeldre,he sn/span>
>  455/a> * -  n-fe se'tivitarmmunt' _reaed.h_ zerospan>
 * -  n-fe se'it_lg a mmunt' islnon-zerospan>
 */
 */an>
 */
 */
__loce" a>   ruct rw_semaphore *__insem(struct rw_semaphore *sem, cot wait swrer)
rwsem_waiter {
a href="+code=seiter" class="sref">rwiter {t" class="sref">wait_list);516 id="L5"6 class="line" name="L5"6>  4565a>        struct task_struct *tas;
>  466/a>        rwiokena>;
rwiter { 0; href="+code=list_het">r class="sref">loct_het">r a>(sem->wait_list);. href="+code=namt" naass="sref">namt" a>, sizuct rwsem_waiter {list;
st" class="sref">wait_list);516 id="L496 class="line" name="L496>  496/a>
wait swrer)
<
rwiter {gt;flags); mp;RWSEM_WAITING_FOR_WRITE 0liou a>;
depont_ e s_wrer;
  4575a>
  467/a>        /* rw (< are noallowr  toagra an>
>  477/a> */////////rw (
 */////////rw-< arleavefe se'it_lg a mmunt' increntat
 */////////rw ontention hspan>
 */////////r/span>
rwiter {gt;flags); mp;RWSEM_WAITING_FOR_WRITE 0<
sem->activity = 0;-
loct_hedela>(&rwiter {gt;list;
st" class="sref">wait_list);518 id="L448 class="line" name="L448>  4484a>                   href="+code=lis" class="sref">tas;
 0; href="+code=liiter" class="sref">rwiter {gt;task;
  4585a>                   an class="comment">/* rwDon'toeouch iter
  468/a>                semmp_mba>(&ast" class="sref">wait_list);518 id="L7"8 class="line" name="L7"8>  478/a>                rwiter {gt;task;
 0; href="+code=liNULLclass="sref">taNULLa>;
>  4888a>                wait s_up_processa>(tas;
st" class="sref">wait_list);518 id="L498 class="line" name="L498>  4989a>                taput_sk_struct" a>(tas;
st" class="sref">wait_list);519 id="L509 class="line" name="L509>  5090a>                liou a>;
/* rwgra 
depont_ e s_wrer;
:a href="lib/rwsem-spinlock.c#L8"9 id="L5"9 class="line" name="L5"9>  4595a>           href="+code=re okenclass="sref">rwiokena>;
 0;
  469/a>          whilsfa href="+code=raiter" class="sref">rwiter {gt;flags); mp;RWSEM_WAITING_FOR_READ  <
  479/a>                list_head namt" a>,  0; href="+code=liiter" class="sref">rwiter {gt;list;
. href="+code=namt" naass="sref">namt" a>,   4898a>
>  4999a>                loct_hedela>(&rwiter {gt;list;
st" class="sref">wait_list);5110 id="L10"  class="line" name="L10">>  5">>a>                   href="+code=lis" class="sref">tas;
 0; href="+code=liiter" class="sref">rwiter {gt;task;
1a>                   href="+code=resmp_mbclass="sref">semmp_mba>(&ast" class="sref">wait_list);5110 id="L12"0 class="line" name="L12"02  5">2a>                   href="+code=seiter" class="sref">rwiter {gt;task;
 0; href="+code=liNULLclass="sref">taNULLa>;
3a>                   href="+code=liit s_up_processclass="sref">wait s_up_processa>(tas;
st" class="sref">wait_list);5110 id="L14"0 class="line" name="L14"04  5">4a>                   href="+code=liput_sk_struct" class="sref">taput_sk_struct" a>(tas;
st" class="sref">wait_list);5110 id="L15"0 class="line" name="L15"05  5">5a>                   href="+code=re okenclass="sref">rwiokena>;
++t" class="sref">wait_list);5110 id="L16"0 class="line" name="L16"06  5">/a>                acct_hetmp" a>(&sem->wait_list);
/a>                  stttttttbreakt" class="sref">wait_list);5110 id="L18"0 class="line" name="L18"08  5">8a>                rwiter { 0; href="+code=list_het">r class="sref">loct_het">r a>(namt" a>, sizuct rwsem_waiter {list;
st" class="sref">wait_list);5110 id="L19"0 class="line" name="L19"09  5">9a>            11#ia href="lib/rwsem-spinlock.c#L501" id="L11"  class="line" name="L11">1  5"11a>           href="+code=sem" class="sref">sem->activity = +0; href="+code=liiokenclass="sref">rwiokena>;
  111/a>
  11    href="+code=RWou class="sref">liou a>;
:a href="lib/rwsem-spinlock.c#L8"1" id="L14"" class="line" name="L14"">  11        stturn sem-&  11    11#da href="lib/rwsem-spinlock.c#L501" id="L17"" class="line" name="L17"">  111/a> *
  1118a> */
  1119a> */
  21inruic/ga href="+code=INloce" naass="sref">__loce" a>   ruct rw_semaphore *  212/a>rwinsem(rw_semaphore *sem)
  21    212/a>        struct rwsem_waiter {
a href="+code=seiter" class="sref">rwiter {t" class="sref">wait_list);511" id="L241" class="line" name="L241">  212/a>        struct task_struct *tas;
  2125a>
  212/a>        sem->activity = 0;-
  2127a>
  212/a>        rwiter { 0; href="+code=list_het">r class="sref">loct_het">r a>(sem->wait_list);. href="+code=namt" naass="sref">namt" a>, sizuct rwsem_waiter {list;
st" class="sref">wait_list);511" id="L291" class="line" name="L291">  21        re href="+code=rast_hedelclass="sref">loct_hedela>(&rwiter {gt;list;
st" class="sref">wait_list);511" id="L301" class="line" name="L301">  313/a>#ia href="lib/rwsem-spinlock.c#L501" id="L311" class="line" name="L311">  3131a>           href="+code=ses" class="sref">tas;
 0; href="+code=liiter" class="sref">rwiter {gt;task;
  3132a>        semmp_mba>(&ast" class="sref">wait_list);511" id="L331" class="line" name="L331">  313/a>        rwiter {gt;task;
 0; href="+code=liNULLclass="sref">taNULLa>;
  313/a>        wait s_up_processa>(tas;
st" class="sref">wait_list);511" id="L351" class="line" name="L351">  3135a>           href="+code=reput_sk_struct" class="sref">taput_sk_struct" a>(tas;
st" class="sref">wait_list);511" id="L361" class="line" name="L361">  313/a>        sem-&  31    3138a>
  3139a> *
  4140a> */< ge
  41   
  41rwinhed.ha>    href="+code=RW__down_reahclass="sref">rwindown_reaha>(rw_semaphore *sem)
  4143a>{
  414/a>        struct rwsem_waiter {
 href="+code=seiter" class="sref">rwiter {t" class="sref">wait_list);511" id="L451" class="line" name="L451">  4145a>        struct task_struct *tas;
  41        flags;
  4147a>
  41        raw_spin_trck_inisave" a>(&sem->wait_lock);flags);
  414/a>
  515/a>        sem->activity = t;acct_hetmp" a>(&sem->wait_list);
<
/* rwgra <
sem->activity =++t" class="sref">wait_list);5115 id="L4315 class="line" name="L4315>  4153a>                   href="+code=liw_spin_unlock_irqrestore" class="sref">raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
liou a>;
>  4155a>        sttas;
 0; href="+code=licurrt">/lass="sref">tacurrt">a>;
waset_sk_struar(tas;
RWTASK_UNINTERRUPTIBL a>);
/*
rwiter {. href="+code=nask" class="sref">task;
 0; href="+code=lis" class="sref">tas;
rwiter {. href="+code=naags" class="sref">flags); 0; href="+code=liSEM_WAITING_FOR_WRAD" class="sref">RWSEM_WAITING_FOR_READ  taget_sk_struct" a>(tas;
st" class="sref">wait_list);5116 id="L4416 class="line" name="L4416>  416/a>
  4165a>           href="+code=rect_headd_skilclass="sref">loct_headd_skila>(&rwiter {. href="+code=nast" class="sref">list;
, mp;sem->wait_list);
>  416/a>#da href="lib/rwsem-spinlock.c#L5016 id="L4716 class="line" name="L4716>  4167a>        /*
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
/*
rwiter {. href="+code=nask" class="sref">task;
wait_list);5117 id="L4417 class="line" name="L4417>  4174a>                   href="+code=lihed.hulwased.hul(&ast" class="sref">wait_list);5117 id="L5"17 class="line" name="L5"17>  4175a>                   href="+code=reset_sk_struarwaset_sk_struar(tas;
RWTASK_UNINTERRUPTIBL a>);
  417/a>        >  4177a>
tas;
gt;wasuar(< 0; href="+code=liTASK_RUNNINGclass="sref">RWTASK_RUNNINGa>  liou a>;
:a href="lib/rwsem-spinlock.c#L8"1  id="L5018 class="line" name="L5018>  518/a>        /*
 * inylock_i for rdingbo --aturn 
  418/a> */
  418/a>  t rwindown_reahrylock_ia>(rw_semaphore *sem)
  418/a>  >  4188a>          signed long flags;
ret = 1;
raw_spin_trck_inisave" a>(&sem->wait_lock);flags);
sem->activity = t;acct_hetmp" a>(&sem->wait_list);
<
  4195a>                   an class="comment">/* rwgra <
  419/a>                sem->activity =++t" class="sref">wait_list);5119 id="L7"19 class="line" name="L7"19>  419/a>                ret = 1;
  419/a>        }
>  419/a>
>  52>>a>           href="+code=INw_spin_unlock_irqrestore" class="sref">raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
ret;
 *
 * - ge
 */an>
 */
rwinhed.ha>    href="+code=RW__down_wrer<_ntor.hclass="sref">rwindown_wrer<_ntor.ha>(rw_semaphore *sem)
cot semubass="a>)
  12#isemub15ss="sref">waset_sk_struar(    href="+code=RWou class="sref2>liou21>  raw_spin_trck_inisave" a>(&sem->wait_lock);<2id="L15""2class="line" name="L15""2  11<2a>    1121=++t" class="ib/rwsem-spinlock.c#L2819 id="L4419 class="line" name="L4419>  4194a>           (sem->activity = t;acct_hetmp" a>(&sem->  112/a>waispinlock.c#L13"9 id="L5"19 class="line" name="L5"19>  4195a>             2ass="comm2nt"> */
sem->  1112a>2*/wait_list);51ck.c#L20"  id="L20"  class="line" name="L20">>  52>>a>           href="+code=INw_spin_unlock_irqrestore" class="sref">raw_spin_unlock_irqrestore(&sem->wait_lock, rw_semap2ore  4154a>                 2> *wase href="lib/rwsem-spinlock.c#L3020 id="L221"2class="line" name="L221"2  21<22);
r2iter<22>;
tas;
 0; h2> *ta5em-spinlock.c#L1217 id="L4817 class="l">  112/a> u h   u h  1u id="L102" class="line"12" class="line"12" class="line"12" clas="sreline" name="L5016>  516/a>        /*
w2inloc2t);. href="+code=namt" na*145a> u h  


rwiter {. hre2lass="sre2">wait_list);511" id2"L29123"line" name="L20">>  52>>a>           ist;
2t" class="sref">wait_lis2)2511" id="L301" class="line" nL1516 id="L4316 class="line" name="L4316>  416/a>        taget_sk_struct" a>(tas;
st" class="sref">wait_list);5116 id="L4416 class="line" name="L4416>  416/a>
  3131a>  2     23emapho2e" class="sref">rw_semap2ore  3132a>    2   rwiter {. href="+code=nast" class="sref">list;
, mp;sem-&2r" class=2sref">rwiter {gt;task */
sem->  1112a>2*/wa3/a>     2  );511" id="L351" clas2="lin23href="+code=seiter" class="sref">rwitera>(&sem->flags);
t2s;
st" class="sref">2ait_l23class="sref">acct_het16/a>
/*2em  4195a>             class="line" name="L4117>  4171a>    2pinlock.c2L501" id="L381" class="l2ne" n24ef="+code=wast" class="sref">listL4217>  4172a>                   (  3139a>acct_hetmp" a>(&r2iter<22>;
tas;
 0; hent">   <2span>
sem->  42sem)
<2 href24ode=wask" class="sref">taskRWTASK_UNINTERRUPTIBL a>);
  417/a>                   href="+code=INw_spin_unlock_/rwsem-spinlock.c#L1217 id="L48172/a>);511"2id="L451" class="line" n2me="L24href="+code=sname="L6"17>  417/a>        task_2truct2/a> *sem->t2ib/rwsem-spinlock.c#L1212 id="2481" class="line" name="L481">  412        */an>
/*  515/a>        2s (flags);
 */tas;
 0; hm-spinloc2.c#L13"" id="L511" class2"line25lock, (&wait_locksem->>  4255a>  spinlock.c#L3418 id="L4418untaans="line" name="L4418>  418/a>untaans="lineoaindicar<  clexclusitarckan>
/*t2=licurrt">/lass="sref">t2currt2>a>;
flags);
semub15ss="sref">waset_sk_struar(<>;
RWcode=sem" class="sref">sem)
task2
 0; href="+code=lis" cl2ss="s2ef">tas;
flags<2a>); 2; href="+code=liSEM_WAITING_FOR_WRAD" 2lass="sre2">RWSEM_WAITING_FOR_READ2/a>  2a href="lib/rwf">raw_spin_trck_inisave" a>(&sem->wait_lock);<2id="L15""2class="line" name="L15""2  11<2a>    1121=++t" class="ib/rwsem-spinlock.c#L2819 id="L4419 clas6 id="L5"26 class="line" name="L5"26>  426class="sref">acct_hetm"sref">sem->activity = t;kilclass=2sref">loct_headd_skila>(2amp;<26name="L5"19>  4195a>                href="+code=sem" class="sref">sem->  112/a>waist;/* rwgra <
wait_lock2/a>, 27ass="sref">RWTASK_UNINTERRUPcomm2nt"> */
sem->  1112a>2*/wab/rwsem-s2inlock.c#L2816 id="L49162class27spinlock.c#L1517 id="L4917 class="lin2be givenh2 seck imr/span>
(&sem-> {. href="+code=nask" c2ass="27class="sref">rwsem_waiter {
a hre2ihed.hul<2lass="sref">wased.hul2&ast"27
  4175a>      2     27="L14204  520/a>
  31  w2set_sk_struar( * - ge  4140a>/*rwinhed.ha>    hhref="+co2e=waruarwa2uarRW    R.own semub15ss="sref">waset_sk_struar(RWTA2K_RUNNINGa>  tas;
r--aw_spin_trck_inisave" a>(&sem->    1121=++t" class="ib/rw="+code=liSEM_WAITING_FOR_WRAD" 2=hed.hul<2omment">/*
acct_hetmp" a>(&  1119a> */
 28     href="+code=reset_sk_struar28ait_list);
>  416/a>#da href="lib/rwsem-spinlock.c#L5016 id="L4716 class="line" name="L4716>  4167a>        /*rw_sema2hore<2a> *  418/a>  >  4188a>    2     29e="L381">  3138a>
fl2gs;
liou a>;
:a hspan class="comment"> * - ge/*rwinhed.ha>    hrwsem_waiter {
 href="+code=seiter" class="sref">rwiter {t" class="sref">wait_list2m-spinloc2.c#L13"9 id="L5"19 class2"line29     href="+code=reset_sk_struar *tas;
  41        flags;
sem->activity =++t" c3ass="sref">wait_list3;51193id="L7"19 class="line" name="href="+code=sem" class="sref">sem->  112/a>    1121=++t" class="ib/rw="+code=liSEM_WAITING_FOR_WRAD" 3href="+co3e=INw_spin_unlock_irqres3ore" 30class="sref">acct_hetmp" a>(& */wai30emapho2e" class="sref">rw_semap2orefla3s);
>  416/a>#da href="lib/rwsem-spinlock.c#L5016 id="L4716 class="line" name="L4716>  4167a>        /*
  111/a>
3et
sem->  11 - justc#L151up>;
," id=ers ak.c#L2front112/c#L2pan cline" name="L12202  52>2a>          tur3e" name="319209  52>9a>  id  * - gerwck.c#L3520 id="L1720 c18/agrade> */ */an>
/*semubass="a>)
<3 href31> *semub15ss="sref">waset_sk_struar(3a href="+3  href="+code=liit s_up_3roces3cla=rast_hedib/rwsem-spinlock. class=s3tarcla=ra3t_hedib/rwsem-spinlock. 3lass=3it)rwait_  R.own     href="+code=RWou class="sref2>liou21>  sem->  112/a>
    1121=++t" class="ib/rw="+code=liSEM_WAITING_FOR_WRAD" 3acct_hetmp" a>(& */tas;
 0; 3pinlock.c3L13"9 id="L5"19 class="l3ne" n32b/rwsem-spinlock.c#L13"8 id="L8"1  cl3it_list);51ck.c#L20"  id="L20"3 clas32ass="sref">RWTASK_UNINTERRUPcomm2nt"> */
sem->  1112a>2*/  111/a>
wait_lockrw_semap2ore


T#L2original LXR software by/c#L22e" classhttp://sourceforge.net/projects/lxan>LXR m-spunclass=",/c#is experipinlal version by/2e" classmailto:lxa@m-sux.none"xa@m-sux.noss=".
"xa.m-sux.no kindly hoa t by/2e" classhttp://www.redpill-m-spro.noneRedpill L-spro ASss=",/provi=er112/L-sux