Add a Racy type to bench tests

This commit is contained in:
Flavio Percoco 2014-12-24 12:59:23 +01:00
parent 29b3698f7f
commit 52072dec0f
2 changed files with 20 additions and 10 deletions

View File

@ -46,7 +46,7 @@ extern crate libc;
use std::io::stdio::{stdin_raw, stdout_raw}; use std::io::stdio::{stdin_raw, stdout_raw};
use std::num::{div_rem}; use std::num::{div_rem};
use std::ptr::{copy_memory}; use std::ptr::{copy_memory, Unique};
use std::io::{IoResult, EndOfFile}; use std::io::{IoResult, EndOfFile};
struct Tables { struct Tables {
@ -219,10 +219,15 @@ fn reverse_complement(seq: &mut [u8], tables: &Tables) {
} }
} }
struct Racy<T>(T);
unsafe impl<T: 'static> Send for Racy<T> {}
/// Executes a closure in parallel over the given iterator over mutable slice. /// Executes a closure in parallel over the given iterator over mutable slice.
/// The closure `f` is run in parallel with an element of `iter`. /// The closure `f` is run in parallel with an element of `iter`.
fn parallel<'a, I, T, F>(mut iter: I, f: F) fn parallel<'a, I, T, F>(mut iter: I, f: F)
where T: Send + Sync, where T: 'a+Send + Sync,
I: Iterator<&'a mut [T]>, I: Iterator<&'a mut [T]>,
F: Fn(&'a mut [T]) + Sync { F: Fn(&'a mut [T]) + Sync {
use std::mem; use std::mem;
@ -234,11 +239,11 @@ fn parallel<'a, I, T, F>(mut iter: I, f: F)
// Need to convert `f` and `chunk` to something that can cross the task // Need to convert `f` and `chunk` to something that can cross the task
// boundary. // boundary.
let f = &f as *const F as *const uint; let f = Racy(&f as *const F as *const uint);
let raw = chunk.repr(); let raw = Racy(chunk.repr());
spawn(move|| { spawn(move|| {
let f = f as *const F; let f = f.0 as *const F;
unsafe { (*f)(mem::transmute(raw)) } unsafe { (*f)(mem::transmute(raw.0)) }
drop(tx) drop(tx)
}); });
} }

View File

@ -108,6 +108,11 @@ fn dot(v: &[f64], u: &[f64]) -> f64 {
v.iter().zip(u.iter()).map(|(a, b)| *a * *b).sum() v.iter().zip(u.iter()).map(|(a, b)| *a * *b).sum()
} }
struct Racy<T>(T);
unsafe impl<T: 'static> Send for Racy<T> {}
// Executes a closure in parallel over the given mutable slice. The closure `f` // Executes a closure in parallel over the given mutable slice. The closure `f`
// is run in parallel and yielded the starting index within `v` as well as a // is run in parallel and yielded the starting index within `v` as well as a
// sub-slice of `v`. // sub-slice of `v`.
@ -122,11 +127,11 @@ fn parallel<'a, T, F>(v: &'a mut [T], f: F)
// Need to convert `f` and `chunk` to something that can cross the task // Need to convert `f` and `chunk` to something that can cross the task
// boundary. // boundary.
let f = &f as *const _ as *const uint; let f = Racy(&f as *const _ as *const uint);
let raw = chunk.repr(); let raw = Racy(chunk.repr());
spawn(move|| { spawn(move|| {
let f = f as *const F; let f = f.0 as *const F;
unsafe { (*f)(i * size, mem::transmute(raw)) } unsafe { (*f)(i * size, mem::transmute(raw.0)) }
drop(tx) drop(tx)
}); });
} }