@@ -95,163 +95,11 @@ fn test_run_in_bare_thread() unsafe {
9595#[ allow( non_camel_case_types) ] // runtime type
9696type rust_port_id = uint ;
9797
98- type GlobalPtr = * libc:: uintptr_t ;
99-
10098fn compare_and_swap ( address : & mut int , oldval : int , newval : int ) -> bool {
10199 let old = rusti:: atomic_cxchg ( address, oldval, newval) ;
102100 old == oldval
103101}
104102
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-
255103/**
256104 * Convert the current task to a 'weak' task temporarily
257105 *
0 commit comments