Blame source/vdo/base/lockCounter.h

Packit Service d40955
/*
Packit Service d40955
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service d40955
 *
Packit Service d40955
 * This program is free software; you can redistribute it and/or
Packit Service d40955
 * modify it under the terms of the GNU General Public License
Packit Service d40955
 * as published by the Free Software Foundation; either version 2
Packit Service d40955
 * of the License, or (at your option) any later version.
Packit Service d40955
 * 
Packit Service d40955
 * This program is distributed in the hope that it will be useful,
Packit Service d40955
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d40955
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service d40955
 * GNU General Public License for more details.
Packit Service d40955
 * 
Packit Service d40955
 * You should have received a copy of the GNU General Public License
Packit Service d40955
 * along with this program; if not, write to the Free Software
Packit Service d40955
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service d40955
 * 02110-1301, USA. 
Packit Service d40955
 *
Packit Service d40955
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/lockCounter.h#2 $
Packit Service d40955
 */
Packit Service d40955
Packit Service d40955
#ifndef LOCK_COUNTER_H
Packit Service d40955
#define LOCK_COUNTER_H
Packit Service d40955
Packit Service d40955
#include "completion.h"
Packit Service d40955
#include "types.h"
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * LockCounter provides a set of shared reference count locks which is safe
Packit Service d40955
 * across multiple zones with a minimum of cross-thread synchronization
Packit Service d40955
 * operations. For each lock in the set, it maintains a set of per-zone lock
Packit Service d40955
 * counts, and a single, atomic count of the number of zones holding locks.
Packit Service d40955
 * Whenever a zone's individual counter for a lock goes from 0 to 1, the
Packit Service d40955
 * zone count for that lock is incremented. Whenever a zone's individual
Packit Service d40955
 * counter for a lock goes from 1 to 0, the zone count for that lock is
Packit Service d40955
 * decremented. If the zone count goes to 0, and the lock counter's
Packit Service d40955
 * completion is not in use, the completion is launched to inform the counter's
Packit Service d40955
 * owner that some lock has been released. It is the owner's responsibility to
Packit Service d40955
 * check for which locks have been released, and to inform the lock counter
Packit Service d40955
 * that it has received the notification by calling acknowledgeUnlock().
Packit Service d40955
 **/
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Create a lock counter.
Packit Service d40955
 *
Packit Service d40955
 * @param [in]  layer           The physical layer of the VDO
Packit Service d40955
 * @param [in]  parent          The parent to notify when the lock count goes
Packit Service d40955
 *                              to zero
Packit Service d40955
 * @param [in]  callback        The function to call when the lock count goes
Packit Service d40955
 *                              to zero
Packit Service d40955
 * @param [in]  threadID        The id of thread on which to run the callback
Packit Service d40955
 * @param [in]  logicalZones    The total number of logical zones
Packit Service d40955
 * @param [in]  physicalZones   The total number of physical zones
Packit Service d40955
 * @param [in]  locks           The number of locks
Packit Service d40955
 * @param [out] lockCounterPtr  A pointer to hold the new counter
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 **/
Packit Service d40955
int makeLockCounter(PhysicalLayer  *layer,
Packit Service d40955
                    void           *parent,
Packit Service d40955
                    VDOAction       callback,
Packit Service d40955
                    ThreadID        threadID,
Packit Service d40955
                    ZoneCount       logicalZones,
Packit Service d40955
                    ZoneCount       physicalZones,
Packit Service d40955
                    BlockCount      locks,
Packit Service d40955
                    LockCounter   **lockCounterPtr)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Destroy a lock counter and NULL out the reference to it.
Packit Service d40955
 *
Packit Service d40955
 * @param lockCounterPtr  A pointer to the lock counter reference to free
Packit Service d40955
 **/
Packit Service d40955
void freeLockCounter(LockCounter **lockCounterPtr);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Check whether a lock is locked for a zone type. If the recovery journal has
Packit Service d40955
 * a lock on the lock number, both logical and physical zones are considered
Packit Service d40955
 * locked.
Packit Service d40955
 *
Packit Service d40955
 * @param lockCounter  The set of locks to check
Packit Service d40955
 * @param lockNumber   The lock to check
Packit Service d40955
 * @param zoneType     The type of the zone
Packit Service d40955
 *
Packit Service d40955
 * @return true if the specified lock has references (is locked)
Packit Service d40955
 **/
Packit Service d40955
bool isLocked(LockCounter *lockCounter,
Packit Service d40955
              BlockCount   lockNumber,
Packit Service d40955
              ZoneType     zoneType)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Initialize the value of the journal zone's counter for a given lock. This
Packit Service d40955
 * must be called from the journal zone.
Packit Service d40955
 *
Packit Service d40955
 * @param counter     The counter to initialize
Packit Service d40955
 * @param lockNumber  Which lock to initialize
Packit Service d40955
 * @param value       The value to set
Packit Service d40955
 **/
Packit Service d40955
void initializeLockCount(LockCounter *counter,
Packit Service d40955
                         BlockCount   lockNumber,
Packit Service d40955
                         uint16_t     value);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Acquire a reference to a given lock in the specified zone. This method must
Packit Service d40955
 * not be used from the journal zone.
Packit Service d40955
 *
Packit Service d40955
 * @param counter     The LockCounter
Packit Service d40955
 * @param lockNumber  Which lock to increment
Packit Service d40955
 * @param zoneType    The type of the zone acquiring the reference
Packit Service d40955
 * @param zoneID      The ID of the zone acquiring the reference
Packit Service d40955
 **/
Packit Service d40955
void acquireLockCountReference(LockCounter *counter,
Packit Service d40955
                               BlockCount   lockNumber,
Packit Service d40955
                               ZoneType     zoneType,
Packit Service d40955
                               ZoneCount    zoneID);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Release a reference to a given lock in the specified zone. This method
Packit Service d40955
 * must not be used from the journal zone.
Packit Service d40955
 *
Packit Service d40955
 * @param counter     The LockCounter
Packit Service d40955
 * @param lockNumber  Which lock to increment
Packit Service d40955
 * @param zoneType    The type of the zone releasing the reference
Packit Service d40955
 * @param zoneID      The ID of the zone releasing the reference
Packit Service d40955
 **/
Packit Service d40955
void releaseLockCountReference(LockCounter *counter,
Packit Service d40955
                               BlockCount   lockNumber,
Packit Service d40955
                               ZoneType     zoneType,
Packit Service d40955
                               ZoneCount    zoneID);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Release a single journal zone reference from the journal zone. This method
Packit Service d40955
 * must be called from the journal zone.
Packit Service d40955
 *
Packit Service d40955
 * @param counter     The counter from which to release a reference
Packit Service d40955
 * @param lockNumber  The lock from which to release a reference
Packit Service d40955
 **/
Packit Service d40955
void releaseJournalZoneReference(LockCounter *counter, BlockCount lockNumber);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Release a single journal zone reference from any zone. This method shouldn't
Packit Service d40955
 * be called from the journal zone as it would be inefficient; use
Packit Service d40955
 * releaseJournalZoneReference() instead.
Packit Service d40955
 *
Packit Service d40955
 * @param counter     The counter from which to release a reference
Packit Service d40955
 * @param lockNumber  The lock from which to release a reference
Packit Service d40955
 **/
Packit Service d40955
void releaseJournalZoneReferenceFromOtherZone(LockCounter *counter,
Packit Service d40955
                                              BlockCount   lockNumber);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Inform a lock counter that an unlock notification was received by the
Packit Service d40955
 * caller.
Packit Service d40955
 *
Packit Service d40955
 * @param counter  The counter to inform
Packit Service d40955
 **/
Packit Service d40955
void acknowledgeUnlock(LockCounter *counter);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Prevent the lock counter from issuing notifications.
Packit Service d40955
 *
Packit Service d40955
 * @param counter  The counter
Packit Service d40955
 *
Packit Service d40955
 * @return true if the lock counter was not notifying and hence
Packit Service d40955
 *         the suspend was efficacious
Packit Service d40955
 **/
Packit Service d40955
bool suspendLockCounter(LockCounter *counter)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Re-allow notifications from a suspended lock counter.
Packit Service d40955
 *
Packit Service d40955
 * @param counter  The counter
Packit Service d40955
 *
Packit Service d40955
 * @return true if the lock counter was suspended
Packit Service d40955
 **/
Packit Service d40955
bool resumeLockCounter(LockCounter *counter)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
#endif // LOCK_COUNTER_H