"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/isc/include/isc/rwlock.h" (7 Sep 2020, 3806 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rwlock.h" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 
   13 #ifndef ISC_RWLOCK_H
   14 #define ISC_RWLOCK_H 1
   15 
   16 #include <inttypes.h>
   17 
   18 /*! \file isc/rwlock.h */
   19 
   20 #include <isc/condition.h>
   21 #include <isc/lang.h>
   22 #include <isc/platform.h>
   23 #include <isc/types.h>
   24 
   25 #if defined(ISC_PLATFORM_HAVESTDATOMIC)
   26 #if defined(__cplusplus)
   27 #include <isc/stdatomic.h>
   28 #else
   29 #include <stdatomic.h>
   30 #endif
   31 #endif
   32 
   33 ISC_LANG_BEGINDECLS
   34 
   35 typedef enum {
   36     isc_rwlocktype_none = 0,
   37     isc_rwlocktype_read,
   38     isc_rwlocktype_write
   39 } isc_rwlocktype_t;
   40 
   41 #ifdef ISC_PLATFORM_USETHREADS
   42 # if defined(ISC_PLATFORM_HAVESTDATOMIC)
   43 #  define ISC_RWLOCK_USEATOMIC 1
   44 #  define ISC_RWLOCK_USESTDATOMIC 1
   45 # else /* defined(ISC_PLATFORM_HAVESTDATOMIC) */
   46 #  if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
   47 #   define ISC_RWLOCK_USEATOMIC 1
   48 #  endif
   49 # endif /* defined(ISC_PLATFORM_HAVESTDATOMIC) */
   50 
   51 struct isc_rwlock {
   52     /* Unlocked. */
   53     unsigned int        magic;
   54     isc_mutex_t     lock;
   55 
   56 #if defined(ISC_RWLOCK_USEATOMIC)
   57     /*
   58      * When some atomic instructions with hardware assistance are
   59      * available, rwlock will use those so that concurrent readers do not
   60      * interfere with each other through mutex as long as no writers
   61      * appear, massively reducing the lock overhead in the typical case.
   62      *
   63      * The basic algorithm of this approach is the "simple
   64      * writer-preference lock" shown in the following URL:
   65      * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html
   66      * but our implementation does not rely on the spin lock unlike the
   67      * original algorithm to be more portable as a user space application.
   68      */
   69 
   70     /* Read or modified atomically. */
   71 #if defined(ISC_RWLOCK_USESTDATOMIC)
   72     atomic_int_fast32_t spins;
   73     atomic_int_fast32_t write_requests;
   74     atomic_int_fast32_t write_completions;
   75     atomic_int_fast32_t cnt_and_flag;
   76     atomic_int_fast32_t write_granted;
   77 #else
   78     int32_t     spins;
   79     int32_t     write_requests;
   80     int32_t     write_completions;
   81     int32_t     cnt_and_flag;
   82     int32_t     write_granted;
   83 #endif
   84 
   85     /* Locked by lock. */
   86     isc_condition_t     readable;
   87     isc_condition_t     writeable;
   88     unsigned int        readers_waiting;
   89 
   90     /* Unlocked. */
   91     unsigned int        write_quota;
   92 
   93 #else  /* ISC_RWLOCK_USEATOMIC */
   94 
   95     /*%< Locked by lock. */
   96     isc_condition_t     readable;
   97     isc_condition_t     writeable;
   98     isc_rwlocktype_t    type;
   99 
  100     /*% The number of threads that have the lock. */
  101     unsigned int        active;
  102 
  103     /*%
  104      * The number of lock grants made since the lock was last switched
  105      * from reading to writing or vice versa; used in determining
  106      * when the quota is reached and it is time to switch.
  107      */
  108     unsigned int        granted;
  109 
  110     unsigned int        spins;
  111     unsigned int        readers_waiting;
  112     unsigned int        writers_waiting;
  113     unsigned int        read_quota;
  114     unsigned int        write_quota;
  115     isc_rwlocktype_t    original;
  116 #endif  /* ISC_RWLOCK_USEATOMIC */
  117 };
  118 #else /* ISC_PLATFORM_USETHREADS */
  119 struct isc_rwlock {
  120     unsigned int        magic;
  121     isc_rwlocktype_t    type;
  122     unsigned int        active;
  123 };
  124 #endif /* ISC_PLATFORM_USETHREADS */
  125 
  126 
  127 isc_result_t
  128 isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
  129         unsigned int write_quota);
  130 
  131 isc_result_t
  132 isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
  133 
  134 isc_result_t
  135 isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
  136 
  137 isc_result_t
  138 isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
  139 
  140 isc_result_t
  141 isc_rwlock_tryupgrade(isc_rwlock_t *rwl);
  142 
  143 void
  144 isc_rwlock_downgrade(isc_rwlock_t *rwl);
  145 
  146 void
  147 isc_rwlock_destroy(isc_rwlock_t *rwl);
  148 
  149 ISC_LANG_ENDDECLS
  150 
  151 #endif /* ISC_RWLOCK_H */