|
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
|