OSDN Git Service

mn10300: Add attribute enabled.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / thread.c
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "runtime.h"
6
7 void
8 runtime_initlock(Lock *l)
9 {
10         l->key = 0;
11         if(sem_init(&l->sem, 0, 0) != 0)
12                 runtime_throw("sem_init failed");
13 }
14
15 static uint32
16 runtime_xadd(uint32 volatile *val, int32 delta)
17 {
18         uint32 oval, nval;
19
20         for(;;){
21                 oval = *val;
22                 nval = oval + delta;
23                 if(runtime_cas(val, oval, nval))
24                         return nval;
25         }
26 }
27
28 // noinline so that runtime_lock doesn't have to split the stack.
29 static void runtime_lock_full(Lock *l) __attribute__ ((noinline));
30
31 static void
32 runtime_lock_full(Lock *l)
33 {
34         if(sem_wait(&l->sem) != 0)
35                 runtime_throw("sem_wait failed");
36 }
37
38 void
39 runtime_lock(Lock *l)
40 {
41         if(m->locks < 0)
42                 runtime_throw("lock count");
43         m->locks++;
44
45         if(runtime_xadd(&l->key, 1) > 1)        // someone else has it; wait
46                 runtime_lock_full(l);
47 }
48
49 static void runtime_unlock_full(Lock *l) __attribute__ ((noinline));
50
51 static void
52 runtime_unlock_full(Lock *l)
53 {
54         if(sem_post(&l->sem) != 0)
55                 runtime_throw("sem_post failed");
56 }
57
58 void
59 runtime_unlock(Lock *l)
60 {
61         m->locks--;
62         if(m->locks < 0)
63                 runtime_throw("lock count");
64
65         if(runtime_xadd(&l->key, -1) > 0)       // someone else is waiting
66                 runtime_unlock_full(l);
67 }
68
69 void
70 runtime_destroylock(Lock *l)
71 {
72         sem_destroy(&l->sem);
73 }