-
Notifications
You must be signed in to change notification settings - Fork 1
Fix memory leak #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix memory leak #59
Changes from all commits
64873ba
347b1ff
117c767
7edd6ae
952a43a
94acc4f
72f2eb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ use std::{ | |
| io::prelude::*, | ||
| net::{Shutdown, TcpStream}, | ||
| process::Command, | ||
| sync::Arc, | ||
| thread, time, | ||
| }; | ||
|
|
||
|
|
@@ -22,6 +23,7 @@ use llvm::execution_engine::*; | |
| use llvm::target::*; | ||
| use llvm_sys::LLVMType; | ||
| use llvm_sys::prelude::*; | ||
| use std::cell::RefCell; | ||
| use std::ffi::{CStr, CString, c_void}; | ||
| use std::mem; | ||
|
|
||
|
|
@@ -129,6 +131,11 @@ pub unsafe extern "C" fn task(name: *const i8, random: bool) -> u64 { | |
| 0 | ||
| } | ||
|
|
||
| thread_local! { | ||
| static LAST_RANDOM_PATH: RefCell<CString> = | ||
| RefCell::new(CString::new("").unwrap()); | ||
| } | ||
|
|
||
| /// Return a randomly generated path. | ||
| /// | ||
| /// # Safety | ||
|
|
@@ -144,7 +151,11 @@ pub unsafe extern "C" fn random_path(base: *const i8) -> *const i8 { | |
| .map(char::from) | ||
| .collect(); | ||
|
|
||
| CString::new(format!("{base}/{uniq}")).unwrap().into_raw() | ||
| LAST_RANDOM_PATH.with(|last| { | ||
| let mut last = last.borrow_mut(); | ||
| *last = CString::new(format!("{base}/{uniq}")).unwrap(); | ||
| last.as_ptr() | ||
| }) | ||
| } | ||
|
|
||
| #[derive(Debug, Clone)] | ||
|
|
@@ -506,21 +517,43 @@ impl Worker for ScriptWorker { | |
| debug!("Distribution {:?}", d); | ||
| let Dist::Exp { rate } = d else { todo!() }; | ||
|
|
||
| loop { | ||
| let worker = self.clone(); | ||
| thread::spawn(move || { | ||
| (worker.jit)(); | ||
| }); | ||
|
|
||
| let interval: f64 = | ||
| thread_rng().sample(Exp::new(*rate).unwrap()); | ||
| debug!("Interval {}", interval); | ||
| thread::sleep(time::Duration::from_secs_f64(interval)); | ||
| } | ||
| const MAX_CONCURRENT: usize = 16; | ||
| let semaphore = Arc::new(( | ||
| std::sync::Mutex::new(0usize), | ||
| std::sync::Condvar::new(), | ||
| )); | ||
|
|
||
| thread::scope(|s| { | ||
| loop { | ||
| { | ||
| let (lock, cvar) = &*semaphore; | ||
| let mut count = cvar | ||
| .wait_while(lock.lock().unwrap(), |c| { | ||
| *c >= MAX_CONCURRENT | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do I see it correctly that this limit maximum number of parallel workers?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. |
||
| }) | ||
| .unwrap(); | ||
| *count += 1; | ||
| } | ||
|
|
||
| let worker = self.clone(); | ||
| let sem = Arc::clone(&semaphore); | ||
| s.spawn(move || { | ||
| (worker.jit)(); | ||
| let (lock, cvar) = &*sem; | ||
| *lock.lock().unwrap() -= 1; | ||
| cvar.notify_one(); | ||
| }); | ||
|
|
||
| let interval: f64 = | ||
| thread_rng().sample(Exp::new(*rate).unwrap()); | ||
| debug!("Interval {}", interval); | ||
| thread::sleep(time::Duration::from_secs_f64(interval)); | ||
| } | ||
| }); | ||
| } | ||
| None => { | ||
| debug!("Single unit"); | ||
| (self.jit)() | ||
| (self.jit)(); | ||
| } | ||
| }; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ultra-nit] We might want to put this in a new type and add something like
.incand.decmethods to remove some verbosity in the loop. But honestly, this way is fine as well.