aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.7/libgo/runtime/sema.goc
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2015-06-17 11:09:54 -0700
committerDan Albert <danalbert@google.com>2015-06-17 14:15:22 -0700
commitf378ebf14df0952eae870c9865bab8326aa8f137 (patch)
tree31794503eb2a8c64ea5f313b93100f1163afcffb /gcc-4.7/libgo/runtime/sema.goc
parent2c58169824949d3a597d9fa81931e001ef9b1bd0 (diff)
downloadtoolchain_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.goc181
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);
-}