]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove non-stdatomic parts of rwlock.{c,h}
authorOndřej Surý <ondrej@sury.org>
Wed, 1 Aug 2018 12:31:29 +0000 (14:31 +0200)
committerOndřej Surý <ondrej@sury.org>
Wed, 8 Aug 2018 07:49:06 +0000 (09:49 +0200)
lib/isc/include/isc/rwlock.h
lib/isc/rwlock.c

index 111a0f6f3e066743611cb15fff01822b8afcb5fb..1691d0d11fa5e4ec3499bfbf6171939da510e656 100644 (file)
@@ -41,7 +41,6 @@ struct isc_rwlock {
        isc_mutex_t             lock;
        isc_int32_t             spins;
 
-#if defined(ISC_RWLOCK_USEATOMIC)
        /*
         * When some atomic instructions with hardware assistance are
         * available, rwlock will use those so that concurrent readers do not
@@ -56,15 +55,9 @@ struct isc_rwlock {
         */
 
        /* Read or modified atomically. */
-#if defined(ISC_RWLOCK_USESTDATOMIC)
        atomic_int_fast32_t     write_requests;
        atomic_int_fast32_t     write_completions;
        atomic_int_fast32_t     cnt_and_flag;
-#else
-       isc_int32_t             write_requests;
-       isc_int32_t             write_completions;
-       isc_int32_t             cnt_and_flag;
-#endif
 
        /* Locked by lock. */
        isc_condition_t         readable;
@@ -76,30 +69,6 @@ struct isc_rwlock {
 
        /* Unlocked. */
        unsigned int            write_quota;
-
-#else  /* ISC_RWLOCK_USEATOMIC */
-
-       /*%< Locked by lock. */
-       isc_condition_t         readable;
-       isc_condition_t         writeable;
-       isc_rwlocktype_t        type;
-
-       /*% The number of threads that have the lock. */
-       unsigned int            active;
-
-       /*%
-        * The number of lock grants made since the lock was last switched
-        * from reading to writing or vice versa; used in determining
-        * when the quota is reached and it is time to switch.
-        */
-       unsigned int            granted;
-
-       unsigned int            readers_waiting;
-       unsigned int            writers_waiting;
-       unsigned int            read_quota;
-       unsigned int            write_quota;
-       isc_rwlocktype_t        original;
-#endif  /* ISC_RWLOCK_USEATOMIC */
 };
 #else /* ISC_PLATFORM_USETHREADS */
 struct isc_rwlock {
index 8c9455932f39724345db765993e9ac65d08bf3bc..f2d96175e81be9b2bfda9f640b3669614aa4864e 100644 (file)
 #define RWLOCK_MAX_ADAPTIVE_COUNT 100
 #endif
 
-#if defined(ISC_RWLOCK_USEATOMIC)
 static isc_result_t
 isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
-#endif
 
 #ifdef ISC_RWLOCK_TRACE
 #include <stdio.h>             /* Required for fprintf/stderr. */
@@ -52,7 +50,6 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
 
 static void
 print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
-#if defined(ISC_RWLOCK_USEATOMIC)
        fprintf(stderr,
                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
                               ISC_MSG_PRINTLOCK2,
@@ -69,26 +66,6 @@ print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                rwl->write_requests, rwl->write_completions,
                rwl->cnt_and_flag, rwl->readers_waiting,
                rwl->write_granted, rwl->write_quota);
-#else
-       fprintf(stderr,
-               isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                              ISC_MSG_PRINTLOCK,
-                              "rwlock %p thread %lu %s(%s): %s, %u active, "
-                              "%u granted, %u rwaiting, %u wwaiting\n"),
-               rwl, isc_thread_self(), operation,
-               (type == isc_rwlocktype_read ?
-                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                               ISC_MSG_READ, "read") :
-                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                               ISC_MSG_WRITE, "write")),
-               (rwl->type == isc_rwlocktype_read ?
-                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                               ISC_MSG_READING, "reading") :
-                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                               ISC_MSG_WRITING, "writing")),
-               rwl->active, rwl->granted,
-               rwl->readers_waiting, rwl->writers_waiting);
-#endif
 }
 #endif /* ISC_RWLOCK_TRACE */
 
@@ -107,7 +84,6 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
        rwl->magic = 0;
 
        rwl->spins = 0;
-#if defined(ISC_RWLOCK_USEATOMIC)
        rwl->write_requests = 0;
        rwl->write_completions = 0;
        rwl->cnt_and_flag = 0;
@@ -120,20 +96,6 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
        if (write_quota == 0)
                write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
        rwl->write_quota = write_quota;
-#else
-       rwl->type = isc_rwlocktype_read;
-       rwl->original = isc_rwlocktype_none;
-       rwl->active = 0;
-       rwl->granted = 0;
-       rwl->readers_waiting = 0;
-       rwl->writers_waiting = 0;
-       if (read_quota == 0)
-               read_quota = RWLOCK_DEFAULT_READ_QUOTA;
-       rwl->read_quota = read_quota;
-       if (write_quota == 0)
-               write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
-       rwl->write_quota = write_quota;
-#endif
 
        result = isc_mutex_init(&rwl->lock);
        if (result != ISC_R_SUCCESS)
@@ -176,16 +138,8 @@ void
 isc_rwlock_destroy(isc_rwlock_t *rwl) {
        REQUIRE(VALID_RWLOCK(rwl));
 
-#if defined(ISC_RWLOCK_USEATOMIC)
        REQUIRE(rwl->write_requests == rwl->write_completions &&
                rwl->cnt_and_flag == 0 && rwl->readers_waiting == 0);
-#else
-       LOCK(&rwl->lock);
-       REQUIRE(rwl->active == 0 &&
-               rwl->readers_waiting == 0 &&
-               rwl->writers_waiting == 0);
-       UNLOCK(&rwl->lock);
-#endif
 
        rwl->magic = 0;
        (void)isc_condition_destroy(&rwl->readable);
@@ -193,8 +147,6 @@ isc_rwlock_destroy(isc_rwlock_t *rwl) {
        DESTROYLOCK(&rwl->lock);
 }
 
-#if defined(ISC_RWLOCK_USEATOMIC)
-
 /*
  * When some architecture-dependent atomic operations are available,
  * rwlock can be more efficient than the generic algorithm defined below.
@@ -283,13 +235,9 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                        UNLOCK(&rwl->lock);
                }
 
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                cntflag = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
                                                    READER_INCR,
                                                    memory_order_relaxed);
-#else
-               cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
-#endif
                POST(cntflag);
                while (1) {
                        if ((rwl->cnt_and_flag & WRITER_ACTIVE) == 0)
@@ -339,12 +287,8 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                isc_int32_t prev_writer;
 
                /* enter the waiting queue, and wait for our turn */
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                prev_writer = atomic_fetch_add_explicit(&rwl->write_requests, 1,
                                                        memory_order_relaxed);
-#else
-               prev_writer = isc_atomic_xadd(&rwl->write_requests, 1);
-#endif
                while (rwl->write_completions != prev_writer) {
                        LOCK(&rwl->lock);
                        if (rwl->write_completions != prev_writer) {
@@ -357,16 +301,10 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                }
 
                while (1) {
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                        int_fast32_t cntflag2 = 0;
                        atomic_compare_exchange_strong_explicit
                                (&rwl->cnt_and_flag, &cntflag2, WRITER_ACTIVE,
                                 memory_order_relaxed, memory_order_relaxed);
-#else
-                       isc_int32_t cntflag2;
-                       cntflag2 = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
-                                                     WRITER_ACTIVE);
-#endif
 
                        if (cntflag2 == 0)
                                break;
@@ -431,26 +369,17 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                        return (ISC_R_LOCKBUSY);
 
                /* Otherwise, be ready for reading. */
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                cntflag = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
                                                    READER_INCR,
                                                    memory_order_relaxed);
-#else
-               cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
-#endif
                if ((cntflag & WRITER_ACTIVE) != 0) {
                        /*
                         * A writer is working.  We lose, and cancel the read
                         * request.
                         */
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                        cntflag = atomic_fetch_sub_explicit
                                (&rwl->cnt_and_flag, READER_INCR,
                                 memory_order_relaxed);
-#else
-                       cntflag = isc_atomic_xadd(&rwl->cnt_and_flag,
-                                                 -READER_INCR);
-#endif
                        /*
                         * If no other readers are waiting and we've suspended
                         * new writers in this short period, wake them up.
@@ -466,29 +395,18 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                }
        } else {
                /* Try locking without entering the waiting queue. */
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                int_fast32_t zero = 0;
                if (!atomic_compare_exchange_strong_explicit
                    (&rwl->cnt_and_flag, &zero, WRITER_ACTIVE,
                     memory_order_relaxed, memory_order_relaxed))
                        return (ISC_R_LOCKBUSY);
-#else
-               cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
-                                            WRITER_ACTIVE);
-               if (cntflag != 0)
-                       return (ISC_R_LOCKBUSY);
-#endif
 
                /*
                 * XXXJT: jump into the queue, possibly breaking the writer
                 * order.
                 */
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                atomic_fetch_sub_explicit(&rwl->write_completions, 1,
                                          memory_order_relaxed);
-#else
-               (void)isc_atomic_xadd(&rwl->write_completions, -1);
-#endif
 
                rwl->write_granted++;
        }
@@ -505,7 +423,6 @@ isc_result_t
 isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
        REQUIRE(VALID_RWLOCK(rwl));
 
-#if defined(ISC_RWLOCK_USESTDATOMIC)
        {
                int_fast32_t reader_incr = READER_INCR;
 
@@ -531,30 +448,6 @@ isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
                        return (ISC_R_LOCKBUSY);
 
        }
-#else
-       {
-               isc_int32_t prevcnt;
-
-               /* Try to acquire write access. */
-               prevcnt = isc_atomic_cmpxchg(&rwl->cnt_and_flag,
-                                            READER_INCR, WRITER_ACTIVE);
-               /*
-                * There must have been no writer, and there must have
-                * been at least one reader.
-                */
-               INSIST((prevcnt & WRITER_ACTIVE) == 0 &&
-                      (prevcnt & ~WRITER_ACTIVE) != 0);
-
-               if (prevcnt == READER_INCR) {
-                       /*
-                        * We are the only reader and have been upgraded.
-                        * Now jump into the head of the writer waiting queue.
-                        */
-                       (void)isc_atomic_xadd(&rwl->write_completions, -1);
-               } else
-                       return (ISC_R_LOCKBUSY);
-       }
-#endif
 
        return (ISC_R_SUCCESS);
 }
@@ -565,7 +458,6 @@ isc_rwlock_downgrade(isc_rwlock_t *rwl) {
 
        REQUIRE(VALID_RWLOCK(rwl));
 
-#if defined(ISC_RWLOCK_USESTDATOMIC)
        {
                /* Become an active reader. */
                prev_readers = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
@@ -580,18 +472,6 @@ isc_rwlock_downgrade(isc_rwlock_t *rwl) {
                atomic_fetch_add_explicit(&rwl->write_completions, 1,
                                          memory_order_relaxed);
        }
-#else
-       {
-               /* Become an active reader. */
-               prev_readers = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
-               /* We must have been a writer. */
-               INSIST((prev_readers & WRITER_ACTIVE) != 0);
-
-               /* Complete write */
-               (void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE);
-               (void)isc_atomic_xadd(&rwl->write_completions, 1);
-       }
-#endif
 
        /* Resume other readers */
        LOCK(&rwl->lock);
@@ -612,13 +492,9 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
 #endif
 
        if (type == isc_rwlocktype_read) {
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                prev_cnt = atomic_fetch_sub_explicit(&rwl->cnt_and_flag,
                                                     READER_INCR,
                                                     memory_order_relaxed);
-#else
-               prev_cnt = isc_atomic_xadd(&rwl->cnt_and_flag, -READER_INCR);
-#endif
                /*
                 * If we're the last reader and any writers are waiting, wake
                 * them up.  We need to wake up all of them to ensure the
@@ -637,15 +513,10 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                 * Reset the flag, and (implicitly) tell other writers
                 * we are done.
                 */
-#if defined(ISC_RWLOCK_USESTDATOMIC)
                atomic_fetch_sub_explicit(&rwl->cnt_and_flag, WRITER_ACTIVE,
                                          memory_order_relaxed);
                atomic_fetch_add_explicit(&rwl->write_completions, 1,
                                          memory_order_relaxed);
-#else
-               (void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE);
-               (void)isc_atomic_xadd(&rwl->write_completions, 1);
-#endif
 
                if (rwl->write_granted >= rwl->write_quota ||
                    rwl->write_requests == rwl->write_completions ||
@@ -683,213 +554,6 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
        return (ISC_R_SUCCESS);
 }
 
-#else /* ISC_RWLOCK_USEATOMIC */
-
-static isc_result_t
-doit(isc_rwlock_t *rwl, isc_rwlocktype_t type, isc_boolean_t nonblock) {
-       isc_boolean_t skip = ISC_FALSE;
-       isc_boolean_t done = ISC_FALSE;
-       isc_result_t result = ISC_R_SUCCESS;
-
-       REQUIRE(VALID_RWLOCK(rwl));
-
-       LOCK(&rwl->lock);
-
-#ifdef ISC_RWLOCK_TRACE
-       print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                                 ISC_MSG_PRELOCK, "prelock"), rwl, type);
-#endif
-
-       if (type == isc_rwlocktype_read) {
-               if (rwl->readers_waiting != 0)
-                       skip = ISC_TRUE;
-               while (!done) {
-                       if (!skip &&
-                           ((rwl->active == 0 ||
-                             (rwl->type == isc_rwlocktype_read &&
-                              (rwl->writers_waiting == 0 ||
-                               rwl->granted < rwl->read_quota)))))
-                       {
-                               rwl->type = isc_rwlocktype_read;
-                               rwl->active++;
-                               rwl->granted++;
-                               done = ISC_TRUE;
-                       } else if (nonblock) {
-                               result = ISC_R_LOCKBUSY;
-                               done = ISC_TRUE;
-                       } else {
-                               skip = ISC_FALSE;
-                               rwl->readers_waiting++;
-                               WAIT(&rwl->readable, &rwl->lock);
-                               rwl->readers_waiting--;
-                       }
-               }
-       } else {
-               if (rwl->writers_waiting != 0)
-                       skip = ISC_TRUE;
-               while (!done) {
-                       if (!skip && rwl->active == 0) {
-                               rwl->type = isc_rwlocktype_write;
-                               rwl->active = 1;
-                               rwl->granted++;
-                               done = ISC_TRUE;
-                       } else if (nonblock) {
-                               result = ISC_R_LOCKBUSY;
-                               done = ISC_TRUE;
-                       } else {
-                               skip = ISC_FALSE;
-                               rwl->writers_waiting++;
-                               WAIT(&rwl->writeable, &rwl->lock);
-                               rwl->writers_waiting--;
-                       }
-               }
-       }
-
-#ifdef ISC_RWLOCK_TRACE
-       print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                                 ISC_MSG_POSTLOCK, "postlock"), rwl, type);
-#endif
-
-       UNLOCK(&rwl->lock);
-
-       return (result);
-}
-
-isc_result_t
-isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
-       isc_int32_t cnt = 0;
-       isc_int32_t max_cnt = rwl->spins * 2 + 10;
-       isc_result_t result = ISC_R_SUCCESS;
-
-       if (max_cnt > RWLOCK_MAX_ADAPTIVE_COUNT)
-               max_cnt = RWLOCK_MAX_ADAPTIVE_COUNT;
-
-       do {
-               if (cnt++ >= max_cnt) {
-                       result = doit(rwl, type, ISC_FALSE);
-                       break;
-               }
-#ifdef ISC_PLATFORM_BUSYWAITNOP
-               ISC_PLATFORM_BUSYWAITNOP;
-#endif
-       } while (doit(rwl, type, ISC_TRUE) != ISC_R_SUCCESS);
-
-       rwl->spins += (cnt - rwl->spins) / 8;
-
-       return (result);
-}
-
-isc_result_t
-isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
-       return (doit(rwl, type, ISC_TRUE));
-}
-
-isc_result_t
-isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
-       isc_result_t result = ISC_R_SUCCESS;
-
-       REQUIRE(VALID_RWLOCK(rwl));
-       LOCK(&rwl->lock);
-       REQUIRE(rwl->type == isc_rwlocktype_read);
-       REQUIRE(rwl->active != 0);
-
-       /* If we are the only reader then succeed. */
-       if (rwl->active == 1) {
-               rwl->original = (rwl->original == isc_rwlocktype_none) ?
-                               isc_rwlocktype_read : isc_rwlocktype_none;
-               rwl->type = isc_rwlocktype_write;
-       } else
-               result = ISC_R_LOCKBUSY;
-
-       UNLOCK(&rwl->lock);
-       return (result);
-}
-
-void
-isc_rwlock_downgrade(isc_rwlock_t *rwl) {
-
-       REQUIRE(VALID_RWLOCK(rwl));
-       LOCK(&rwl->lock);
-       REQUIRE(rwl->type == isc_rwlocktype_write);
-       REQUIRE(rwl->active == 1);
-
-       rwl->type = isc_rwlocktype_read;
-       rwl->original = (rwl->original == isc_rwlocktype_none) ?
-                       isc_rwlocktype_write : isc_rwlocktype_none;
-       /*
-        * Resume processing any read request that were blocked when
-        * we upgraded.
-        */
-       if (rwl->original == isc_rwlocktype_none &&
-           (rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota) &&
-           rwl->readers_waiting > 0)
-               BROADCAST(&rwl->readable);
-
-       UNLOCK(&rwl->lock);
-}
-
-isc_result_t
-isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
-
-       REQUIRE(VALID_RWLOCK(rwl));
-       LOCK(&rwl->lock);
-       REQUIRE(rwl->type == type);
-
-       UNUSED(type);
-
-#ifdef ISC_RWLOCK_TRACE
-       print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                                 ISC_MSG_PREUNLOCK, "preunlock"), rwl, type);
-#endif
-
-       INSIST(rwl->active > 0);
-       rwl->active--;
-       if (rwl->active == 0) {
-               if (rwl->original != isc_rwlocktype_none) {
-                       rwl->type = rwl->original;
-                       rwl->original = isc_rwlocktype_none;
-               }
-               if (rwl->type == isc_rwlocktype_read) {
-                       rwl->granted = 0;
-                       if (rwl->writers_waiting > 0) {
-                               rwl->type = isc_rwlocktype_write;
-                               SIGNAL(&rwl->writeable);
-                       } else if (rwl->readers_waiting > 0) {
-                               /* Does this case ever happen? */
-                               BROADCAST(&rwl->readable);
-                       }
-               } else {
-                       if (rwl->readers_waiting > 0) {
-                               if (rwl->writers_waiting > 0 &&
-                                   rwl->granted < rwl->write_quota) {
-                                       SIGNAL(&rwl->writeable);
-                               } else {
-                                       rwl->granted = 0;
-                                       rwl->type = isc_rwlocktype_read;
-                                       BROADCAST(&rwl->readable);
-                               }
-                       } else if (rwl->writers_waiting > 0) {
-                               rwl->granted = 0;
-                               SIGNAL(&rwl->writeable);
-                       } else {
-                               rwl->granted = 0;
-                       }
-               }
-       }
-       INSIST(rwl->original == isc_rwlocktype_none);
-
-#ifdef ISC_RWLOCK_TRACE
-       print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
-                                 ISC_MSG_POSTUNLOCK, "postunlock"),
-                  rwl, type);
-#endif
-
-       UNLOCK(&rwl->lock);
-
-       return (ISC_R_SUCCESS);
-}
-
-#endif /* ISC_RWLOCK_USEATOMIC */
 #else /* ISC_PLATFORM_USETHREADS */
 
 isc_result_t