diff options
author | Dan Albert <danalbert@google.com> | 2015-06-17 11:09:54 -0700 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2015-06-17 14:15:22 -0700 |
commit | f378ebf14df0952eae870c9865bab8326aa8f137 (patch) | |
tree | 31794503eb2a8c64ea5f313b93100f1163afcffb /gcc-4.7/libgo/runtime/sema.goc | |
parent | 2c58169824949d3a597d9fa81931e001ef9b1bd0 (diff) | |
download | toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.tar.gz toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.tar.bz2 toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.zip |
Delete old versions of GCC.
Change-Id: I710f125d905290e1024cbd67f48299861790c66c
Diffstat (limited to 'gcc-4.7/libgo/runtime/sema.goc')
-rw-r--r-- | gcc-4.7/libgo/runtime/sema.goc | 181 |
1 files changed, 0 insertions, 181 deletions
diff --git a/gcc-4.7/libgo/runtime/sema.goc b/gcc-4.7/libgo/runtime/sema.goc deleted file mode 100644 index ff9c4f2e1..000000000 --- a/gcc-4.7/libgo/runtime/sema.goc +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Semaphore implementation exposed to Go. -// Intended use is provide a sleep and wakeup -// primitive that can be used in the contended case -// of other synchronization primitives. -// Thus it targets the same goal as Linux's futex, -// but it has much simpler semantics. -// -// That is, don't think of these as semaphores. -// Think of them as a way to implement sleep and wakeup -// such that every sleep is paired with a single wakeup, -// even if, due to races, the wakeup happens before the sleep. -// -// See Mullender and Cox, ``Semaphores in Plan 9,'' -// http://swtch.com/semaphore.pdf - -package sync -#include "runtime.h" -#include "arch.h" - -typedef struct Sema Sema; -struct Sema -{ - uint32 volatile *addr; - G *g; - Sema *prev; - Sema *next; -}; - -typedef struct SemaRoot SemaRoot; -struct SemaRoot -{ - Lock; - Sema *head; - Sema *tail; - // Number of waiters. Read w/o the lock. - uint32 volatile nwait; -}; - -// Prime to not correlate with any user patterns. -#define SEMTABLESZ 251 - -static union -{ - SemaRoot; - uint8 pad[CacheLineSize]; -} semtable[SEMTABLESZ]; - -static SemaRoot* -semroot(uint32 volatile *addr) -{ - return &semtable[((uintptr)addr >> 3) % SEMTABLESZ]; -} - -static void -semqueue(SemaRoot *root, uint32 volatile *addr, Sema *s) -{ - s->g = runtime_g(); - s->addr = addr; - s->next = nil; - s->prev = root->tail; - if(root->tail) - root->tail->next = s; - else - root->head = s; - root->tail = s; -} - -static void -semdequeue(SemaRoot *root, Sema *s) -{ - if(s->next) - s->next->prev = s->prev; - else - root->tail = s->prev; - if(s->prev) - s->prev->next = s->next; - else - root->head = s->next; - s->prev = nil; - s->next = nil; -} - -static int32 -cansemacquire(uint32 volatile *addr) -{ - uint32 v; - - while((v = runtime_atomicload(addr)) > 0) - if(runtime_cas(addr, v, v-1)) - return 1; - return 0; -} - -void -runtime_semacquire(uint32 volatile *addr) -{ - G *g; - Sema s; - SemaRoot *root; - - // Easy case. - if(cansemacquire(addr)) - return; - - // Harder case: - // increment waiter count - // try cansemacquire one more time, return if succeeded - // enqueue itself as a waiter - // sleep - // (waiter descriptor is dequeued by signaler) - g = runtime_g(); - root = semroot(addr); - for(;;) { - - runtime_lock(root); - // Add ourselves to nwait to disable "easy case" in semrelease. - runtime_xadd(&root->nwait, 1); - // Check cansemacquire to avoid missed wakeup. - if(cansemacquire(addr)) { - runtime_xadd(&root->nwait, -1); - runtime_unlock(root); - return; - } - // Any semrelease after the cansemacquire knows we're waiting - // (we set nwait above), so go to sleep. - semqueue(root, addr, &s); - g->status = Gwaiting; - g->waitreason = "semacquire"; - runtime_unlock(root); - runtime_gosched(); - if(cansemacquire(addr)) - return; - } -} - -void -runtime_semrelease(uint32 volatile *addr) -{ - Sema *s; - SemaRoot *root; - - root = semroot(addr); - runtime_xadd(addr, 1); - - // Easy case: no waiters? - // This check must happen after the xadd, to avoid a missed wakeup - // (see loop in semacquire). - if(runtime_atomicload(&root->nwait) == 0) - return; - - // Harder case: search for a waiter and wake it. - runtime_lock(root); - if(runtime_atomicload(&root->nwait) == 0) { - // The count is already consumed by another goroutine, - // so no need to wake up another goroutine. - runtime_unlock(root); - return; - } - for(s = root->head; s; s = s->next) { - if(s->addr == addr) { - runtime_xadd(&root->nwait, -1); - semdequeue(root, s); - break; - } - } - runtime_unlock(root); - if(s) - runtime_ready(s->g); -} - -func runtime_Semacquire(addr *uint32) { - runtime_semacquire(addr); -} - -func runtime_Semrelease(addr *uint32) { - runtime_semrelease(addr); -} |