Exemplo n.º 1
0
void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) {
  internal::AtomicWord state = internal::Acquire_Load(once);
  // Fast path. The provided closure was already executed.
  if (state == ONCE_STATE_DONE) {
    return;
  }
  // The closure execution did not complete yet. The once object can be in one
  // of the two following states:
  //   - UNINITIALIZED: We are the first thread calling this function.
  //   - EXECUTING_CLOSURE: Another thread is already executing the closure.
  //
  // First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE
  // atomically.
  state = internal::Acquire_CompareAndSwap(
      once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE);
  if (state == ONCE_STATE_UNINITIALIZED) {
    // We are the first thread to call this function, so we have to call the
    // closure.
    closure->Run();
    internal::Release_Store(once, ONCE_STATE_DONE);
  } else {
    // Another thread has already started executing the closure. We need to
    // wait until it completes the initialization.
    while (state == ONCE_STATE_EXECUTING_CLOSURE) {
      // Note that futex() could be used here on Linux as an improvement.
      SchedYield();
      state = internal::Acquire_Load(once);
    }
  }
}
Exemplo n.º 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;
}
Exemplo n.º 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;
}
Exemplo n.º 4
0
int main()
{
	SchedSet(NULL, NULL, SCHED_RR, NULL);
	SyncTypeCreate(_NTO_SYNC_SEM, &Semaphore, NULL);		// initial count: 0
	
	ThreadCreate(NULL, Thread1, NULL, NULL);
	ThreadCreate(NULL, Thread1, NULL, NULL);
	sleep(3);
	ThreadCreate(NULL, Thread2, NULL, NULL);
	SchedYield();
			
	sleep(11);
	return(0);
}
Exemplo n.º 5
0
/*-
 *-----------------------------------------------------------------------
 * Reset --
 *	Tell DIX to reset itself when SIG_TERM is received.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	clientsDoomed is set 1 and the dispatched is told to yield...
 *
 *-----------------------------------------------------------------------
 */
int
Reset()
{
    clientsDoomed = 1;
    SchedYield();
}