Back to index

lightning-sunbird  0.9+nobinonly
Classes | Typedefs | Functions
mdcriticalregion.c File Reference
#include "mdcriticalregion.h"
#include <MacErrors.h>

Go to the source code of this file.

Classes

struct  MDCriticalRegionData_struct

Typedefs

typedef struct
MDCriticalRegionData_struct 
MDCriticalRegionData
typedef struct
MDCriticalRegionData_struct
MDCriticalRegionDataPtr

Functions

OSStatus MD_CriticalRegionCreate (MDCriticalRegionID *outCriticalRegionID)
OSStatus MD_CriticalRegionDelete (MDCriticalRegionID inCriticalRegionID)
OSStatus MD_CriticalRegionEnter (MDCriticalRegionID inCriticalRegionID, Duration inTimeout)
OSStatus MD_CriticalRegionExit (MDCriticalRegionID inCriticalRegionID)

Class Documentation

struct MDCriticalRegionData_struct

Definition at line 50 of file mdcriticalregion.c.

Class Members
UInt32 mDepthCount
MPSemaphoreID mMPSemaphoreID
MPTaskID mMPTaskID

Typedef Documentation


Function Documentation

Definition at line 58 of file mdcriticalregion.c.

{
  MDCriticalRegionDataPtr newCriticalRegionPtr;
  MPSemaphoreID           mpSemaphoreID;
  OSStatus                err = noErr;

  if (outCriticalRegionID == NULL)
    return paramErr;

  *outCriticalRegionID = NULL;

  newCriticalRegionPtr = (MDCriticalRegionDataPtr)MPAllocateAligned(sizeof(MDCriticalRegionData),
                        kMPAllocateDefaultAligned, kMPAllocateClearMask);
  if (newCriticalRegionPtr == NULL)
    return memFullErr;

  // Note: this semaphore is pre-fired (ready!)
  err = MPCreateBinarySemaphore(&mpSemaphoreID);
  if (err == noErr)
  {
    newCriticalRegionPtr->mMPTaskID = kInvalidID;
    newCriticalRegionPtr->mDepthCount = 0;
    newCriticalRegionPtr->mMPSemaphoreID = mpSemaphoreID;

    *outCriticalRegionID = (MDCriticalRegionID)newCriticalRegionPtr;
  }
  else
  {
    MPFree((LogicalAddress)newCriticalRegionPtr);
  }

  return err;
}

Here is the call graph for this function:

Definition at line 93 of file mdcriticalregion.c.

{
  MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
  OSStatus                err = noErr;

  if (criticalRegion == NULL)
    return paramErr;

  if ((criticalRegion->mMPTaskID != kInvalidID) && (criticalRegion->mDepthCount > 0))
    return kMPInsufficientResourcesErr;

  if (criticalRegion->mMPSemaphoreID != kInvalidID)
    err = MPDeleteSemaphore(criticalRegion->mMPSemaphoreID);
  if (noErr != err) return err;

  criticalRegion->mMPSemaphoreID = kInvalidID;
  MPFree((LogicalAddress) criticalRegion);

  return noErr;
}

Here is the call graph for this function:

OSStatus MD_CriticalRegionEnter ( MDCriticalRegionID  inCriticalRegionID,
Duration  inTimeout 
)

Definition at line 115 of file mdcriticalregion.c.

{
  MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
  MPTaskID                currentTaskID = MPCurrentTaskID();
  OSStatus                err = noErr;

  if (criticalRegion == NULL)
    return paramErr;

  // if I'm inside the critical region...
  if (currentTaskID == criticalRegion->mMPTaskID)
  {
    // bump my depth
    criticalRegion->mDepthCount++;
    // and continue
    return noErr;
  }

  // wait for the ready semaphore
  err = MPWaitOnSemaphore(criticalRegion->mMPSemaphoreID, inTimeout);
  // we didn't get it. return the error
  if (noErr != err) return err;

  // we got it!
  criticalRegion->mMPTaskID = currentTaskID;
  criticalRegion->mDepthCount = 1;

  return noErr;
}

Here is the call graph for this function:

Definition at line 146 of file mdcriticalregion.c.

{
  MDCriticalRegionDataPtr   criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
  MPTaskID                  currentTaskID = MPCurrentTaskID();
  OSStatus                  err = noErr;

  // if we don't own the critical region...
  if (currentTaskID != criticalRegion->mMPTaskID)
    return kMPInsufficientResourcesErr;

  // if we aren't at a depth...
  if (criticalRegion->mDepthCount == 0)
    return kMPInsufficientResourcesErr;

  // un-bump my depth
  criticalRegion->mDepthCount--;

  // if we just bottomed out...
  if (criticalRegion->mDepthCount == 0)
  {
    // release ownership of the structure
    criticalRegion->mMPTaskID = kInvalidID;
    // and signal the ready semaphore
    err = MPSignalSemaphore(criticalRegion->mMPSemaphoreID);
  }
  return err;
}

Here is the call graph for this function: