INT32
EFIAPI
TestAndClearBit (
  IN INT32            Bit,
  IN VOID             *Address
  )
{
  UINT16    Word, Read;
  UINT16    Mask;

  //
  // Calculate the effective address relative to 'Address' based on the
  // higher order bits of 'Bit'. Use signed shift instead of division to
  // ensure we round towards -Inf, and end up with a positive shift in
  // 'Bit', even if 'Bit' itself is negative.
  //
  Address += (Bit >> 4) * sizeof(UINT16);
  Mask = 1U << (Bit & 15);

  for (Word = *(UINT16 *) Address; Word & Mask; Word = Read) {
    Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask);
    if (Read == Word) {
      return 1;
    }
  }
  return 0;
}
Exemple #2
0
static NTSTATUS
GnttabRevokeForeignAccess(
    IN  PINTERFACE              Interface,
    IN  PXENBUS_GNTTAB_CACHE    Cache,
    IN  BOOLEAN                 Locked,
    IN  PXENBUS_GNTTAB_ENTRY    Entry
    )
{
    PXENBUS_GNTTAB_CONTEXT      Context = Interface->Context;
    volatile SHORT              *flags;
    ULONG                       Attempt;
    NTSTATUS                    status;

    ASSERT3U(Entry->Magic, ==, XENBUS_GNTTAB_ENTRY_MAGIC);
    ASSERT3U(Entry->Reference, >=, XENBUS_GNTTAB_RESERVED_ENTRY_COUNT);
    ASSERT3U(Entry->Reference, <, (Context->FrameIndex + 1) * XENBUS_GNTTAB_ENTRY_PER_FRAME);

    flags = (volatile SHORT *)&Context->Table[Entry->Reference].flags;

    Attempt = 0;
    while (Attempt++ < 100) {
        uint16_t    Old;
        uint16_t    New;

        Old = *flags;
        Old &= ~(GTF_reading | GTF_writing);

        New = Old & ~GTF_permit_access;

        if (InterlockedCompareExchange16(flags, New, Old) == Old)
            break;

        SchedYield();
    }

    status = STATUS_UNSUCCESSFUL;
    if (Attempt == 100)
        goto fail1;

    RtlZeroMemory(&Context->Table[Entry->Reference],
                  sizeof (grant_entry_v1_t));
    RtlZeroMemory(&Entry->Entry,
                  sizeof (grant_entry_v1_t));

    XENBUS_CACHE(Put,
                 &Context->CacheInterface,
                 Cache->Cache,
                 Entry,
                 Locked);

    return STATUS_SUCCESS;

fail1:
    Error("fail1 (%08x)\n", status);

    return status;
}
Exemple #3
0
static NTSTATUS
GnttabRevokeForeignAccess(
    IN  PXENBUS_GNTTAB_CONTEXT      Context,
    IN  PXENBUS_GNTTAB_CACHE        Cache,
    IN  BOOLEAN                     Locked,
    IN  PXENBUS_GNTTAB_DESCRIPTOR   Descriptor
)
{
    grant_entry_v1_t                *Entry;
    volatile SHORT                  *Flags;
    ULONG                           Attempt;
    NTSTATUS                        status;

    ASSERT3U(Descriptor->Magic, ==, GNTTAB_DESCRIPTOR_MAGIC);
    ASSERT3U(Descriptor->Reference, >=, GNTTAB_RESERVED_ENTRY_COUNT);
    ASSERT3U(Descriptor->Reference, <, (Context->FrameIndex + 1) * GNTTAB_ENTRY_PER_FRAME);

    Entry = &Context->Entry[Descriptor->Reference];
    Flags = (volatile SHORT *)&Entry->flags;

    Attempt = 0;
    while (Attempt++ < 100) {
        uint16_t    Old;
        uint16_t    New;

        Old = *Flags;
        Old &= ~(GTF_reading | GTF_writing);

        New = Old & ~GTF_permit_access;

        if (InterlockedCompareExchange16(Flags, New, Old) == Old)
            break;

        SchedYield();
    }

    status = STATUS_UNSUCCESSFUL;
    if (Attempt == 100)
        goto fail1;

    RtlZeroMemory(Entry, sizeof (grant_entry_v1_t));
    RtlZeroMemory(&Descriptor->Entry, sizeof (grant_entry_v1_t));

    CACHE(Put,
          Context->CacheInterface,
          Cache->Cache,
          Descriptor,
          Locked);

    return STATUS_SUCCESS;

fail1:
    Error("fail1 (%08x)\n", status);

    return status;
}
Exemple #4
0
bool trySet(Type *p, Type newVal, Type oldVal)
  {
  bool success = false;

#if defined(X_MSVC)
  xAssertIsSpecificAligned(p, 8);
  // try to lock the updating flag, if we cant, someone else is working.
  success = InterlockedCompareExchange16(p, newVal, oldVal) == oldVal;

#else
  success = __sync_val_compare_and_swap(p, oldVal, newVal) == oldVal;
#endif

  return success;
  }