OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package runtime | 5 package runtime |
6 #include "runtime.h" | 6 #include "runtime.h" |
7 #include "arch_GOARCH.h" | 7 #include "arch_GOARCH.h" |
8 #include "type.h" | 8 #include "type.h" |
9 #include "race.h" | 9 #include "race.h" |
10 #include "malloc.h" | 10 #include "malloc.h" |
11 #include "chan.h" | 11 #include "chan.h" |
| 12 #include "mgc0.h" |
| 13 #include "typekind.h" |
12 #include "../../cmd/ld/textflag.h" | 14 #include "../../cmd/ld/textflag.h" |
13 | 15 |
14 uint32 runtime·Hchansize = sizeof(Hchan); | |
15 | |
16 static void dequeueg(WaitQ*); | 16 static void dequeueg(WaitQ*); |
17 static SudoG* dequeue(WaitQ*); | 17 static SudoG* dequeue(WaitQ*); |
18 static void enqueue(WaitQ*, SudoG*); | 18 static void enqueue(WaitQ*, SudoG*); |
19 static void destroychan(Hchan*); | |
20 static void racesync(Hchan*, SudoG*); | 19 static void racesync(Hchan*, SudoG*); |
21 | 20 |
| 21 static Type hchanType; |
| 22 static String hchanStr; |
| 23 |
| 24 void |
| 25 runtime·chaninit(void) |
| 26 { |
| 27 int32 i, off; |
| 28 byte *mask; |
| 29 |
| 30 // Generate (bare minimum) type descriptor for Hchan. |
| 31 hchanType.size = sizeof(Hchan); |
| 32 hchanStr = runtime·gostringnocopy((byte*)"chan"); |
| 33 hchanType.string = &hchanStr; |
| 34 // Hchan has only one interesting pointer -- buf. |
| 35 off = offsetof(Hchan, buf)/PtrSize*gcBits; |
| 36 if(off%8) |
| 37 runtime·throw("makechan: unaligned buffer"); |
| 38 if(off+8 >= sizeof(hchanType.gc)*8) |
| 39 runtime·throw("makechan: gc mask does not fit"); |
| 40 mask = (byte*)hchanType.gc; |
| 41 for(i = 0; i < off/8; i++) |
| 42 mask[i] = (BitsScalar<<2) | (BitsScalar<<6); |
| 43 mask[off/8] = (BitsPointer<<2) | (BitsDead<<6); |
| 44 } |
| 45 |
22 static Hchan* | 46 static Hchan* |
23 makechan(ChanType *t, int64 hint) | 47 makechan(ChanType *t, int64 hint) |
24 { | 48 { |
25 Hchan *c; | 49 Hchan *c; |
26 Type *elem; | 50 Type *elem; |
27 | 51 |
28 elem = t->elem; | 52 elem = t->elem; |
29 | 53 |
30 // compiler checks this but be safe. | 54 // compiler checks this but be safe. |
31 if(elem->size >= (1<<16)) | 55 if(elem->size >= (1<<16)) |
32 runtime·throw("makechan: invalid channel element type"); | 56 runtime·throw("makechan: invalid channel element type"); |
33 if((sizeof(*c)%MAXALIGN) != 0 || elem->align > MAXALIGN) | 57 if((sizeof(*c)%MAXALIGN) != 0 || elem->align > MAXALIGN) |
34 runtime·throw("makechan: bad alignment"); | 58 runtime·throw("makechan: bad alignment"); |
35 | 59 |
36 if(hint < 0 || (intgo)hint != hint || (elem->size > 0 && hint > (MaxMem
- sizeof(*c)) / elem->size)) | 60 if(hint < 0 || (intgo)hint != hint || (elem->size > 0 && hint > (MaxMem
- sizeof(*c)) / elem->size)) |
37 runtime·panicstring("makechan: size out of range"); | 61 runtime·panicstring("makechan: size out of range"); |
38 | 62 |
39 » // allocate memory in one call | 63 » if((elem->kind&KindNoPointers) || hint == 0) { |
40 » c = (Hchan*)runtime·mallocgc(sizeof(*c) + hint*elem->size, nil, 0); | 64 » » // allocate memory in one call |
| 65 » » c = (Hchan*)runtime·mallocgc(sizeof(*c) + hint*elem->size, nil,
FlagNoScan); |
| 66 » » if(hint > 0 && elem->size != 0) |
| 67 » » » c->buf = (byte*)(c+1); |
| 68 » » else |
| 69 » » » c->buf = (byte*)c; // race detector uses this location
for synchronization |
| 70 » } else { |
| 71 » » c = (Hchan*)runtime·cnew(&hchanType); |
| 72 » » c->buf = runtime·cnewarray(elem, hint); |
| 73 » } |
41 c->elemsize = elem->size; | 74 c->elemsize = elem->size; |
42 c->elemtype = elem; | 75 c->elemtype = elem; |
43 c->dataqsiz = hint; | 76 c->dataqsiz = hint; |
44 | 77 |
45 if(debug) | 78 if(debug) |
46 runtime·printf("makechan: chan=%p; elemsize=%D; elemalg=%p; data
qsiz=%D\n", | 79 runtime·printf("makechan: chan=%p; elemsize=%D; elemalg=%p; data
qsiz=%D\n", |
47 c, (int64)elem->size, elem->alg, (int64)c->dataqsiz); | 80 c, (int64)elem->size, elem->alg, (int64)c->dataqsiz); |
48 | 81 |
49 return c; | 82 return c; |
50 } | 83 } |
(...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 } | 1174 } |
1142 | 1175 |
1143 static void | 1176 static void |
1144 racesync(Hchan *c, SudoG *sg) | 1177 racesync(Hchan *c, SudoG *sg) |
1145 { | 1178 { |
1146 runtime·racerelease(chanbuf(c, 0)); | 1179 runtime·racerelease(chanbuf(c, 0)); |
1147 runtime·raceacquireg(sg->g, chanbuf(c, 0)); | 1180 runtime·raceacquireg(sg->g, chanbuf(c, 0)); |
1148 runtime·racereleaseg(sg->g, chanbuf(c, 0)); | 1181 runtime·racereleaseg(sg->g, chanbuf(c, 0)); |
1149 runtime·raceacquire(chanbuf(c, 0)); | 1182 runtime·raceacquire(chanbuf(c, 0)); |
1150 } | 1183 } |
OLD | NEW |