/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkSharedMutex.h"

#include "SkAtomics.h"
#include "SkSemaphore.h"
#include "SkTypes.h"

#if defined(THREAD_SANITIZER)

/* Report that a lock has been created at address "lock". */
#define ANNOTATE_RWLOCK_CREATE(lock) \
    AnnotateRWLockCreate(__FILE__, __LINE__, lock)

/* Report that the lock at address "lock" is about to be destroyed. */
#define ANNOTATE_RWLOCK_DESTROY(lock) \
    AnnotateRWLockDestroy(__FILE__, __LINE__, lock)

/* Report that the lock at address "lock" has been acquired.
   is_w=1 for writer lock, is_w=0 for reader lock. */
#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
    AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w)

/* Report that the lock at address "lock" is about to be released. */
#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
  AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w)

#ifdef DYNAMIC_ANNOTATIONS_WANT_ATTRIBUTE_WEAK
# ifdef __GNUC__
#  define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK __attribute__((weak))
# else
/* TODO(glider): for Windows support we may want to change this macro in order
   to prepend __declspec(selectany) to the annotations' declarations. */
#  error weak annotations are not supported for your compiler
# endif
#else
# define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK
#endif

extern "C" {
void AnnotateRWLockCreate(
    const char *file, int line,
    const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK;
void AnnotateRWLockDestroy(
    const char *file, int line,
    const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK;
void AnnotateRWLockAcquired(
    const char *file, int line,
    const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK;
void AnnotateRWLockReleased(
    const char *file, int line,
    const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK;
}

#else

#define ANNOTATE_RWLOCK_CREATE(lock)
#define ANNOTATE_RWLOCK_DESTROY(lock)
#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w)
#define ANNOTATE_RWLOCK_RELEASED(lock, is_w)

#endif

// The fQueueCounts fields holds many counts in an int32_t in order to make managing them atomic.
// These three counts must be the same size, so each gets 10 bits. The 10 bits represent
// the log of the count which is 1024.
//
// The three counts held in fQueueCounts are:
// * Shared - the number of shared lock holders currently running.
// * WaitingExclusive - the number of threads waiting for an exclusive lock.
// * WaitingShared - the number of threads waiting to run while waiting for an exclusive thread
//   to finish.
static const int kLogThreadCount = 10;

enum {
    kSharedOffset          = (0 * kLogThreadCount),
    kWaitingExlusiveOffset = (1 * kLogThreadCount),
    kWaitingSharedOffset   = (2 * kLogThreadCount),
    kSharedMask            = ((1 << kLogThreadCount) - 1) << kSharedOffset,
    kWaitingExclusiveMask  = ((1 << kLogThreadCount) - 1) << kWaitingExlusiveOffset,
    kWaitingSharedMask     = ((1 << kLogThreadCount) - 1) << kWaitingSharedOffset,
};

SkSharedMutex::SkSharedMutex() : fQueueCounts(0) { ANNOTATE_RWLOCK_CREATE(this); }
SkSharedMutex::~SkSharedMutex() {  ANNOTATE_RWLOCK_DESTROY(this); }
void SkSharedMutex::acquire() {
    // Increment the count of exclusive queue waiters.
    int32_t oldQueueCounts = fQueueCounts.fetch_add(1 << kWaitingExlusiveOffset,
                                                    sk_memory_order_acquire);

    // If there are no other exclusive waiters and no shared threads are running then run
    // else wait.
    if ((oldQueueCounts & kWaitingExclusiveMask) > 0 || (oldQueueCounts & kSharedMask) > 0) {
        fExclusiveQueue.wait();
    }
    ANNOTATE_RWLOCK_ACQUIRED(this, 1);
}

void SkSharedMutex::release() {
    ANNOTATE_RWLOCK_RELEASED(this, 1);

    int32_t oldQueueCounts = fQueueCounts.load(sk_memory_order_relaxed);
    int32_t waitingShared;
    int32_t newQueueCounts;
    do {
        newQueueCounts = oldQueueCounts;

        // Decrement exclusive waiters.
        newQueueCounts -= 1 << kWaitingExlusiveOffset;

        // The number of threads waiting to acquire a shared lock.
        waitingShared = (oldQueueCounts & kWaitingSharedMask) >> kWaitingSharedOffset;

        // If there are any move the counts of all the shared waiters to actual shared. They are
        // going to run next.
        if (waitingShared > 0) {

            // Set waiting shared to zero.
            newQueueCounts &= ~kWaitingSharedMask;

            // Because this is the exclusive release, then there are zero readers. So, the bits
            // for shared locks should be zero. Since those bits are zero, we can just |= in the
            // waitingShared count instead of clearing with an &= and then |= the count.
            newQueueCounts |= waitingShared << kSharedOffset;
        }

    } while (!fQueueCounts.compare_exchange(&oldQueueCounts, newQueueCounts,
                                            sk_memory_order_release, sk_memory_order_relaxed));

    if (waitingShared > 0) {
        // Run all the shared.
        fSharedQueue.signal(waitingShared);
    } else if ((newQueueCounts & kWaitingExclusiveMask) > 0) {
        // Run a single exclusive waiter.
        fExclusiveQueue.signal();
    }
}

#ifdef SK_DEBUG
void SkSharedMutex::assertHeld() const {
    int32_t queueCounts = fQueueCounts.load(sk_memory_order_relaxed);
    // These are very loose asserts about the mutex being held exclusively.
    SkASSERTF(0 == (queueCounts & kSharedMask),
              "running shared: %d, exclusive: %d, waiting shared: %d",
              (queueCounts & kSharedMask) >> kSharedOffset,
              (queueCounts & kWaitingExclusiveMask) >> kWaitingExlusiveOffset,
              (queueCounts & kWaitingSharedMask) >> kWaitingSharedOffset);
    SkASSERTF((queueCounts & kWaitingExclusiveMask) > 0,
              "running shared: %d, exclusive: %d, waiting shared: %d",
              (queueCounts & kSharedMask) >> kSharedOffset,
              (queueCounts & kWaitingExclusiveMask) >> kWaitingExlusiveOffset,
              (queueCounts & kWaitingSharedMask) >> kWaitingSharedOffset);
}
#endif

void SkSharedMutex::acquireShared() {
    int32_t oldQueueCounts = fQueueCounts.load(sk_memory_order_relaxed);
    int32_t newQueueCounts;
    do {
        newQueueCounts = oldQueueCounts;
        // If there are waiting exclusives then this shared lock waits else it runs.
        if ((newQueueCounts & kWaitingExclusiveMask) > 0) {
            newQueueCounts += 1 << kWaitingSharedOffset;
        } else {
            newQueueCounts += 1 << kSharedOffset;
        }
    } while (!fQueueCounts.compare_exchange(&oldQueueCounts, newQueueCounts,
                                            sk_memory_order_acquire, sk_memory_order_relaxed));

    // If there are waiting exclusives, then this shared waits until after it runs.
    if ((newQueueCounts & kWaitingExclusiveMask) > 0) {
        fSharedQueue.wait();
    }
    ANNOTATE_RWLOCK_ACQUIRED(this, 0);
   
}

void SkSharedMutex::releaseShared() {
    ANNOTATE_RWLOCK_RELEASED(this, 0);

    // Decrement the shared count.
    int32_t oldQueueCounts = fQueueCounts.fetch_add(~0U << kSharedOffset,
                                                    sk_memory_order_release);

    // If shared count is going to zero (because the old count == 1) and there are exclusive
    // waiters, then run a single exclusive waiter.
    if (((oldQueueCounts & kSharedMask) >> kSharedOffset) == 1
        && (oldQueueCounts & kWaitingExclusiveMask) > 0) {
        fExclusiveQueue.signal();
    }
}

#ifdef SK_DEBUG
void SkSharedMutex::assertHeldShared() const {
    int32_t queueCounts = fQueueCounts.load(sk_memory_order_relaxed);
    // A very loose assert about the mutex being shared.
    SkASSERTF((queueCounts & kSharedMask) > 0,
              "running shared: %d, exclusive: %d, waiting shared: %d",
              (queueCounts & kSharedMask) >> kSharedOffset,
              (queueCounts & kWaitingExclusiveMask) >> kWaitingExlusiveOffset,
              (queueCounts & kWaitingSharedMask) >> kWaitingSharedOffset);
}

#endif
