Blame source/vdo/base/pbnLock.h

Packit Service 75d76b
/*
Packit Service 75d76b
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service 75d76b
 *
Packit Service 75d76b
 * This program is free software; you can redistribute it and/or
Packit Service 75d76b
 * modify it under the terms of the GNU General Public License
Packit Service 75d76b
 * as published by the Free Software Foundation; either version 2
Packit Service 75d76b
 * of the License, or (at your option) any later version.
Packit Service 75d76b
 * 
Packit Service 75d76b
 * This program is distributed in the hope that it will be useful,
Packit Service 75d76b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 75d76b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 75d76b
 * GNU General Public License for more details.
Packit Service 75d76b
 * 
Packit Service 75d76b
 * You should have received a copy of the GNU General Public License
Packit Service 75d76b
 * along with this program; if not, write to the Free Software
Packit Service 75d76b
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 75d76b
 * 02110-1301, USA. 
Packit Service 75d76b
 *
Packit Service 75d76b
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/pbnLock.h#3 $
Packit Service 75d76b
 */
Packit Service 75d76b
Packit Service 75d76b
#ifndef PBN_LOCK_H
Packit Service 75d76b
#define PBN_LOCK_H
Packit Service 75d76b
Packit Service 75d76b
#include "atomic.h"
Packit Service 75d76b
#include "types.h"
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * The type of a PBN lock.
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef enum {
Packit Service 75d76b
  VIO_READ_LOCK = 0,
Packit Service 75d76b
  VIO_WRITE_LOCK,
Packit Service 75d76b
  VIO_COMPRESSED_WRITE_LOCK,
Packit Service 75d76b
  VIO_BLOCK_MAP_WRITE_LOCK,
Packit Service 75d76b
} PBNLockType;
Packit Service 75d76b
Packit Service 75d76b
typedef struct pbnLockImplementation PBNLockImplementation;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A PBN lock.
Packit Service 75d76b
 **/
Packit Service 75d76b
struct pbnLock {
Packit Service 75d76b
  /** The implementation of the lock */
Packit Service 75d76b
  const PBNLockImplementation *implementation;
Packit Service 75d76b
Packit Service 75d76b
  /** The number of VIOs holding or sharing this lock */
Packit Service 75d76b
  VIOCount holderCount;
Packit Service 75d76b
  /**
Packit Service 75d76b
   * The number of compressed block writers holding a share of this lock while
Packit Service 75d76b
   * they are acquiring a reference to the PBN.
Packit Service 75d76b
   **/
Packit Service 75d76b
  uint8_t fragmentLocks;
Packit Service 75d76b
Packit Service 75d76b
  /**
Packit Service 75d76b
   * Whether the locked PBN has been provisionally referenced on behalf of the
Packit Service 75d76b
   * lock holder.
Packit Service 75d76b
   **/
Packit Service 75d76b
  bool hasProvisionalReference;
Packit Service 75d76b
Packit Service 75d76b
  /**
Packit Service 75d76b
   * For read locks, the number of references that were known to be available
Packit Service 75d76b
   * on the locked block at the time the lock was acquired.
Packit Service 75d76b
   **/
Packit Service 75d76b
  uint8_t incrementLimit;
Packit Service 75d76b
Packit Service 75d76b
  /**
Packit Service 75d76b
   * For read locks, the number of DataVIOs that have tried to claim one of
Packit Service 75d76b
   * the available increments during the lifetime of the lock. Each claim will
Packit Service 75d76b
   * first increment this counter, so it can exceed the increment limit.
Packit Service 75d76b
   **/
Packit Service 75d76b
  Atomic32 incrementsClaimed;
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Initialize a PBNLock.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param lock  The lock to initialize
Packit Service 75d76b
 * @param type  The type of the lock
Packit Service 75d76b
 **/
Packit Service 75d76b
void initializePBNLock(PBNLock *lock, PBNLockType type);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Check whether a PBNLock is a read lock.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param lock  The lock to check
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return true if the lock is a read lock
Packit Service 75d76b
 **/
Packit Service 75d76b
bool isPBNReadLock(const PBNLock *lock)
Packit Service 75d76b
  __attribute__((warn_unused_result));
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Downgrade a PBN write lock to a PBN read lock. The lock holder count is
Packit Service 75d76b
 * cleared and the caller is responsible for setting the new count.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param lock  The PBN write lock to downgrade
Packit Service 75d76b
 **/
Packit Service 75d76b
void downgradePBNWriteLock(PBNLock *lock);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Try to claim one of the available reference count increments on a read
Packit Service 75d76b
 * lock. Claims may be attempted from any thread. A claim is only valid until
Packit Service 75d76b
 * the PBN lock is released.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param lock  The PBN read lock from which to claim an increment
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return true if the claim succeeded, guaranteeing one
Packit Service 75d76b
 *         increment can be made without overflowing the PBN's reference count
Packit Service 75d76b
 **/
Packit Service 75d76b
bool claimPBNLockIncrement(PBNLock *lock)
Packit Service 75d76b
  __attribute__((warn_unused_result));
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Check whether a PBN lock has a provisional reference.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param lock  The PBN lock
Packit Service 75d76b
 **/
Packit Service 75d76b
static inline bool hasProvisionalReference(PBNLock *lock)
Packit Service 75d76b
{
Packit Service 75d76b
  return ((lock != NULL) && lock->hasProvisionalReference);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Inform a PBN lock that it is responsible for a provisional reference.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param lock  The PBN lock
Packit Service 75d76b
 **/
Packit Service 75d76b
void assignProvisionalReference(PBNLock *lock);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Inform a PBN lock that it is no longer responsible for a provisional
Packit Service 75d76b
 * reference.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param lock  The PBN lock
Packit Service 75d76b
 **/
Packit Service 75d76b
void unassignProvisionalReference(PBNLock *lock);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * If the lock is responsible for a provisional reference, release that
Packit Service 75d76b
 * reference. This method is called when the lock is released.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param lock       The lock
Packit Service 75d76b
 * @param lockedPBN  The PBN covered by the lock
Packit Service 75d76b
 * @param allocator  The block allocator from which to release the reference
Packit Service 75d76b
 **/
Packit Service 75d76b
void releaseProvisionalReference(PBNLock             *lock,
Packit Service 75d76b
                                 PhysicalBlockNumber  lockedPBN,
Packit Service 75d76b
                                 BlockAllocator      *allocator);
Packit Service 75d76b
Packit Service 75d76b
#endif /* PBN_LOCK_H */