Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(362)

Side by Side Diff: src/pkg/runtime/cgo/gcc_darwin_386.c

Issue 109050043: code review 109050043: all: remove 'extern register M *m' from runtime (Closed)
Patch Set: diff -r 7d2e78c502ab https://code.google.com/p/go/ Created 10 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include <string.h> /* for strerror */ 5 #include <string.h> /* for strerror */
6 #include <pthread.h> 6 #include <pthread.h>
7 #include <signal.h> 7 #include <signal.h>
8 #include "libcgo.h" 8 #include "libcgo.h"
9 9
10 static void* threadentry(void*); 10 static void* threadentry(void*);
11 static pthread_key_t k1, k2; 11 static pthread_key_t k1;
12 12
13 #define magic1 (0x23581321U) 13 #define magic1 (0x23581321U)
14 14
15 static void 15 static void
16 inittls(void) 16 inittls(void)
17 { 17 {
18 » uint32 x, y; 18 » uint32 x;
19 pthread_key_t tofree[128], k; 19 pthread_key_t tofree[128], k;
20 int i, ntofree; 20 int i, ntofree;
21 int havek1, havek2;
22 21
23 /* 22 /*
24 » * Allocate thread-local storage slots for m, g. 23 » * Allocate thread-local storage slot for g.
25 * The key numbers start at 0x100, and we expect to be 24 * The key numbers start at 0x100, and we expect to be
26 * one of the early calls to pthread_key_create, so we 25 * one of the early calls to pthread_key_create, so we
27 » * should be able to get pretty low numbers. 26 » * should be able to get a pretty low number.
28 * 27 *
29 * In Darwin/386 pthreads, %gs points at the thread 28 * In Darwin/386 pthreads, %gs points at the thread
30 * structure, and each key is an index into the thread-local 29 * structure, and each key is an index into the thread-local
31 * storage array that begins at offset 0x48 within in that structure. 30 * storage array that begins at offset 0x48 within in that structure.
32 * It may happen that we are not quite the first function to try 31 * It may happen that we are not quite the first function to try
33 * to allocate thread-local storage keys, so instead of depending 32 * to allocate thread-local storage keys, so instead of depending
34 » * on getting 0x100 and 0x101, we try for 0x108 and 0x109, 33 » * on getting 0x100, we try for 0x108, allocating keys until
35 » * allocating keys until we get the ones we want and then freeing 34 » * we get the one we want and then freeing the ones we didn't want.
36 » * the ones we didn't want.
37 * 35 *
38 » * Thus the final offsets to use in %gs references are 36 » * Thus the final offset to use in %gs references is
39 » * 0x48+4*0x108 = 0x468 and 0x48+4*0x109 = 0x46c. 37 » * 0x48+4*0x108 = 0x468.
40 * 38 *
41 » * The linker and runtime hard-code these constant offsets 39 » * The linker and runtime hard-code this constant offset
42 » * from %gs where we expect to find m and g. 40 » * from %gs where we expect to find g.
43 * Known to ../../../cmd/8l/obj.c:/468 41 * Known to ../../../cmd/8l/obj.c:/468
minux 2014/06/16 21:32:11 it's now at: ../../../liblink/sym.c:/468 however,
rsc 2014/06/24 20:08:17 Done.
44 * and to ../sys_darwin_386.s:/468 42 * and to ../sys_darwin_386.s:/468
45 * 43 *
46 * This is truly disgusting and a bit fragile, but taking care 44 * This is truly disgusting and a bit fragile, but taking care
47 * of it here protects the rest of the system from damage. 45 * of it here protects the rest of the system from damage.
48 * The alternative would be to use a global variable that 46 * The alternative would be to use a global variable that
49 * held the offset and refer to that variable each time we 47 * held the offset and refer to that variable each time we
50 » * need a %gs variable (m or g). That approach would 48 » * need a %gs variable (g). That approach would
51 * require an extra instruction and memory reference in 49 * require an extra instruction and memory reference in
52 * every stack growth prolog and would also require 50 * every stack growth prolog and would also require
53 * rewriting the code that 8c generates for extern registers. 51 * rewriting the code that 8c generates for extern registers.
54 * 52 *
55 * Things get more disgusting on OS X 10.7 Lion. 53 * Things get more disgusting on OS X 10.7 Lion.
56 * The 0x48 base mentioned above is the offset of the tsd 54 * The 0x48 base mentioned above is the offset of the tsd
57 * array within the per-thread structure on Leopard and Snow Leopard. 55 * array within the per-thread structure on Leopard and Snow Leopard.
58 * On Lion, the base moved a little, so while the math above 56 * On Lion, the base moved a little, so while the math above
59 * still applies, the base is different. Thus, we cannot 57 * still applies, the base is different. Thus, we cannot
60 * look for specific key values if we want to build binaries 58 * look for specific key values if we want to build binaries
61 * that run on both systems. Instead, forget about the 59 * that run on both systems. Instead, forget about the
62 * specific key values and just allocate and initialize per-thread 60 * specific key values and just allocate and initialize per-thread
63 * storage until we find a key that writes to the memory location 61 * storage until we find a key that writes to the memory location
64 * we want. Then keep that key. 62 * we want. Then keep that key.
65 */ 63 */
66 havek1 = 0;
67 havek2 = 0;
68 ntofree = 0; 64 ntofree = 0;
69 » while(!havek1 || !havek2) { 65 » for(;;) {
70 if(pthread_key_create(&k, nil) < 0) { 66 if(pthread_key_create(&k, nil) < 0) {
71 fprintf(stderr, "runtime/cgo: pthread_key_create failed\ n"); 67 fprintf(stderr, "runtime/cgo: pthread_key_create failed\ n");
72 abort(); 68 abort();
73 } 69 }
74 pthread_setspecific(k, (void*)magic1); 70 pthread_setspecific(k, (void*)magic1);
75 asm volatile("movl %%gs:0x468, %0" : "=r"(x)); 71 asm volatile("movl %%gs:0x468, %0" : "=r"(x));
76 » » asm volatile("movl %%gs:0x46c, %0" : "=r"(y)); 72 » » pthread_setspecific(k, 0);
77 if(x == magic1) { 73 if(x == magic1) {
78 havek1 = 1;
79 k1 = k; 74 k1 = k;
80 » » } else if(y == magic1) { 75 » » » break;
81 » » » havek2 = 1;
82 » » » k2 = k;
83 » » } else {
84 » » » if(ntofree >= nelem(tofree)) {
85 » » » » fprintf(stderr, "runtime/cgo: could not obtain p thread_keys\n");
86 » » » » fprintf(stderr, "\ttried");
87 » » » » for(i=0; i<ntofree; i++)
88 » » » » » fprintf(stderr, " %#x", (unsigned)tofree [i]);
89 » » » » fprintf(stderr, "\n");
90 » » » » abort();
91 » » » }
92 » » » tofree[ntofree++] = k;
93 } 76 }
94 » » pthread_setspecific(k, 0); 77 » » if(ntofree >= nelem(tofree)) {
78 » » » fprintf(stderr, "runtime/cgo: could not obtain pthread_k eys\n");
79 » » » fprintf(stderr, "\ttried");
80 » » » for(i=0; i<ntofree; i++)
81 » » » » fprintf(stderr, " %#x", (unsigned)tofree[i]);
82 » » » fprintf(stderr, "\n");
83 » » » abort();
84 » » }
95 } 85 }
iant 2014/06/16 20:32:34 You've dropped the line tofree[ntofree++] = k;
rsc 2014/06/24 20:08:17 Done.
96 86
97 /* 87 /*
98 » * We got the keys we wanted. Free the others. 88 » * We got the key we wanted. Free the others.
99 */ 89 */
100 for(i=0; i<ntofree; i++) 90 for(i=0; i<ntofree; i++)
101 pthread_key_delete(tofree[i]); 91 pthread_key_delete(tofree[i]);
102 } 92 }
103 93
104 void 94 void
105 x_cgo_init(G *g) 95 x_cgo_init(G *g)
106 { 96 {
107 pthread_attr_t attr; 97 pthread_attr_t attr;
108 size_t size; 98 size_t size;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 141
152 ts.g->stackbase = (uintptr)&ts; 142 ts.g->stackbase = (uintptr)&ts;
153 143
154 /* 144 /*
155 * _cgo_sys_thread_start set stackguard to stack size; 145 * _cgo_sys_thread_start set stackguard to stack size;
156 * change to actual guard pointer. 146 * change to actual guard pointer.
157 */ 147 */
158 ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096; 148 ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
159 149
160 pthread_setspecific(k1, (void*)ts.g); 150 pthread_setspecific(k1, (void*)ts.g);
161 pthread_setspecific(k2, (void*)ts.m);
162 151
163 crosscall_386(ts.fn); 152 crosscall_386(ts.fn);
164 return nil; 153 return nil;
165 } 154 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b