@@ -95,163 +95,11 @@ fn test_run_in_bare_thread() unsafe {
95
95
#[ allow( non_camel_case_types) ] // runtime type
96
96
type rust_port_id = uint ;
97
97
98
- type GlobalPtr = * libc:: uintptr_t ;
99
-
100
98
fn compare_and_swap ( address : & mut int , oldval : int , newval : int ) -> bool {
101
99
let old = rusti:: atomic_cxchg ( address, oldval, newval) ;
102
100
old == oldval
103
101
}
104
102
105
- /**
106
- * Atomically gets a channel from a pointer to a pointer-sized memory location
107
- * or, if no channel exists creates and installs a new channel and sets up a
108
- * new task to receive from it.
109
- */
110
- pub unsafe fn chan_from_global_ptr < T : Owned > (
111
- global : GlobalPtr ,
112
- task_fn : fn ( ) -> task:: TaskBuilder ,
113
- f : fn ~( oldcomm:: Port < T > )
114
- ) -> oldcomm:: Chan < T > {
115
-
116
- enum Msg {
117
- Proceed ,
118
- Abort
119
- }
120
-
121
- log ( debug, ~"ENTERING chan_from_global_ptr, before is_prob_zero check") ;
122
- let is_probably_zero = * global == 0 u;
123
- log ( debug, ~"after is_prob_zero check") ;
124
- if is_probably_zero {
125
- log ( debug, ~"is probably zero...");
126
- // There's no global channel. We must make it
127
-
128
- let (setup1_po, setup1_ch) = pipes::stream();
129
- let (setup2_po, setup2_ch) = pipes::stream();
130
-
131
- // FIXME #4422: Ugly type inference hint
132
- let setup2_po: pipes::Port<Msg> = setup2_po;
133
-
134
- do task_fn().spawn |move f, move setup1_ch, move setup2_po| {
135
- let po = oldcomm::Port::<T>();
136
- let ch = oldcomm::Chan(&po);
137
- setup1_ch.send(ch);
138
-
139
- // Wait to hear if we are the official instance of
140
- // this global task
141
- match setup2_po.recv() {
142
- Proceed => f(move po),
143
- Abort => ()
144
- }
145
- };
146
-
147
- log(debug,~" before setup recv..");
148
- // This is the proposed global channel
149
- let ch = setup1_po.recv();
150
- // 0 is our sentinal value. It is not a valid channel
151
- assert *ch != 0;
152
-
153
- // Install the channel
154
- log(debug,~" BEFORE COMPARE AND SWAP ") ;
155
- let swapped = compare_and_swap (
156
- cast:: reinterpret_cast ( & global) ,
157
- 0 , cast:: reinterpret_cast ( & ch) ) ;
158
- log ( debug, fmt ! ( "AFTER .. swapped? %?" , swapped) ) ;
159
-
160
- if swapped {
161
- // Success!
162
- setup2_ch. send ( Proceed ) ;
163
- ch
164
- } else {
165
- // Somebody else got in before we did
166
- setup2_ch. send ( Abort ) ;
167
- cast:: reinterpret_cast ( & * global)
168
- }
169
- } else {
170
- log ( debug, ~"global != 0 ") ;
171
- cast:: reinterpret_cast ( & * global)
172
- }
173
- }
174
-
175
- #[ test]
176
- pub fn test_from_global_chan1 ( ) {
177
-
178
- // This is unreadable, right?
179
-
180
- // The global channel
181
- let globchan = 0 ;
182
- let globchanp = ptr:: addr_of ( & globchan) ;
183
-
184
- // Create the global channel, attached to a new task
185
- let ch = unsafe {
186
- do chan_from_global_ptr ( globchanp, task:: task) |po| {
187
- let ch = oldcomm:: recv ( po) ;
188
- oldcomm:: send ( ch, true ) ;
189
- let ch = oldcomm:: recv ( po) ;
190
- oldcomm:: send ( ch, true ) ;
191
- }
192
- } ;
193
- // Talk to it
194
- let po = oldcomm:: Port ( ) ;
195
- oldcomm:: send ( ch, oldcomm:: Chan ( & po) ) ;
196
- assert oldcomm:: recv ( po) == true ;
197
-
198
- // This one just reuses the previous channel
199
- let ch = unsafe {
200
- do chan_from_global_ptr ( globchanp, task:: task) |po| {
201
- let ch = oldcomm:: recv ( po) ;
202
- oldcomm:: send ( ch, false ) ;
203
- }
204
- } ;
205
-
206
- // Talk to the original global task
207
- let po = oldcomm:: Port ( ) ;
208
- oldcomm:: send ( ch, oldcomm:: Chan ( & po) ) ;
209
- assert oldcomm:: recv ( po) == true ;
210
- }
211
-
212
- #[ test]
213
- pub fn test_from_global_chan2( ) {
214
-
215
- for iter:: repeat( 100 ) {
216
- // The global channel
217
- let globchan = 0 ;
218
- let globchanp = ptr:: addr_of ( & globchan) ;
219
-
220
- let resultpo = oldcomm:: Port ( ) ;
221
- let resultch = oldcomm:: Chan ( & resultpo) ;
222
-
223
- // Spawn a bunch of tasks that all want to compete to
224
- // create the global channel
225
- for uint:: range( 0 , 10 ) |i| {
226
- do task:: spawn {
227
- let ch = unsafe {
228
- do chan_from_global_ptr(
229
- globchanp, task:: task) |po| {
230
-
231
- for uint:: range( 0 , 10 ) |_j| {
232
- let ch = oldcomm:: recv( po) ;
233
- oldcomm:: send( ch, { i} ) ;
234
- }
235
- }
236
- } ;
237
- let po = oldcomm:: Port ( ) ;
238
- oldcomm:: send( ch, oldcomm:: Chan ( & po) ) ;
239
- // We are The winner if our version of the
240
- // task was installed
241
- let winner = oldcomm:: recv( po) ;
242
- oldcomm:: send( resultch, winner == i) ;
243
- }
244
- }
245
- // There should be only one winner
246
- let mut winners = 0 u;
247
- for uint:: range( 0 u, 10 u) |_i| {
248
- let res = oldcomm:: recv( resultpo) ;
249
- if res { winners += 1 u } ;
250
- }
251
- assert winners == 1 u;
252
- }
253
- }
254
-
255
103
/**
256
104
* Convert the current task to a 'weak' task temporarily
257
105
*
0 commit comments