From 3a5f80e15392935093fa57c2d0f861f327e7e738 Mon Sep 17 00:00:00 2001 From: Tim Warren Date: Thu, 10 Dec 2015 14:14:30 -0500 Subject: [PATCH] First rust programs --- .gitignore | 2 + dining_philosophers/Cargo.lock | 4 ++ dining_philosophers/Cargo.toml | 4 ++ dining_philosophers/src/main.rs | 65 +++++++++++++++++++++++++++++++++ embed/Cargo.lock | 4 ++ embed/Cargo.toml | 8 ++++ embed/embed.js | 11 ++++++ embed/embed.py | 7 ++++ embed/embed.rb | 11 ++++++ embed/pure-ruby-embed.rb | 19 ++++++++++ embed/src/lib.rs | 19 ++++++++++ guessing_game/Cargo.lock | 41 +++++++++++++++++++++ guessing_game/Cargo.toml | 7 ++++ guessing_game/src/main.rs | 38 +++++++++++++++++++ 14 files changed, 240 insertions(+) create mode 100644 .gitignore create mode 100644 dining_philosophers/Cargo.lock create mode 100644 dining_philosophers/Cargo.toml create mode 100644 dining_philosophers/src/main.rs create mode 100644 embed/Cargo.lock create mode 100644 embed/Cargo.toml create mode 100644 embed/embed.js create mode 100644 embed/embed.py create mode 100644 embed/embed.rb create mode 100644 embed/pure-ruby-embed.rb create mode 100644 embed/src/lib.rs create mode 100644 guessing_game/Cargo.lock create mode 100644 guessing_game/Cargo.toml create mode 100644 guessing_game/src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ae3820 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/target +**/node_modules \ No newline at end of file diff --git a/dining_philosophers/Cargo.lock b/dining_philosophers/Cargo.lock new file mode 100644 index 0000000..53372d9 --- /dev/null +++ b/dining_philosophers/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "dining_philosophers" +version = "0.1.0" + diff --git a/dining_philosophers/Cargo.toml b/dining_philosophers/Cargo.toml new file mode 100644 index 0000000..872d503 --- /dev/null +++ b/dining_philosophers/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "dining_philosophers" +version = "0.1.0" +authors = ["Tim Warren "] diff --git a/dining_philosophers/src/main.rs b/dining_philosophers/src/main.rs new file mode 100644 index 0000000..d2ed9b5 --- /dev/null +++ b/dining_philosophers/src/main.rs @@ -0,0 +1,65 @@ +use std::thread; +use std::sync::{Mutex, Arc}; // Arc == atomic reference count + +struct Philosopher { + name: String, + left: usize, + right: usize, +} + +impl Philosopher { + fn new(name: &str, left: usize, right: usize) -> Philosopher { + Philosopher { + name: name.to_string(), + left: left, + right: right, + } + } + + fn eat(&self, table: &Table) { + let _left = table.forks[self.left].lock().unwrap(); + thread::sleep_ms(150); + let _right = table.forks[self.right].lock().unwrap(); + + println!("{} is eating.", self.name); + + thread::sleep_ms(1000); + + println!("{} is done eating.", self.name); + } +} + +struct Table { + forks: Vec>, +} + +fn main() { + let table = Arc::new(Table { forks: vec![ + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + ]}); + + let philosophers = vec![ + Philosopher::new("Judith Butler", 0, 1), + Philosopher::new("Gilles Deleuze", 1, 2), + Philosopher::new("Karl Marx", 2, 3), + Philosopher::new("Emma Goldman", 3, 4), + Philosopher::new("Michel Foucault", 0, 4), // Left-handed to prevent deadlock + ]; + + let handles: Vec<_> = philosophers.into_iter().map(|p| { + // This increments the refernce count + let table = table.clone(); + + thread::spawn(move || { + p.eat(&table); + }) + }).collect(); + + for h in handles { + h.join().unwrap(); + } +} diff --git a/embed/Cargo.lock b/embed/Cargo.lock new file mode 100644 index 0000000..eefe950 --- /dev/null +++ b/embed/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "embed" +version = "0.1.0" + diff --git a/embed/Cargo.toml b/embed/Cargo.toml new file mode 100644 index 0000000..e4eb028 --- /dev/null +++ b/embed/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "embed" +version = "0.1.0" +authors = ["Tim Warren "] + +[lib] +name = "embed" +crate-type = ["dylib"] \ No newline at end of file diff --git a/embed/embed.js b/embed/embed.js new file mode 100644 index 0000000..f1695e6 --- /dev/null +++ b/embed/embed.js @@ -0,0 +1,11 @@ +'use strict'; + +let ffi = require('ffi'); + +let lib = ffi.Library('target/release/libembed', { + process: ['void', []] +}); + +lib.process(); + +console.log("done!"); \ No newline at end of file diff --git a/embed/embed.py b/embed/embed.py new file mode 100644 index 0000000..14dfc8e --- /dev/null +++ b/embed/embed.py @@ -0,0 +1,7 @@ +from ctypes import cdll + +lib = cdll.LoadLibrary("target/release/libembed.dylib") + +lib.process() + +print("done!") \ No newline at end of file diff --git a/embed/embed.rb b/embed/embed.rb new file mode 100644 index 0000000..5168f43 --- /dev/null +++ b/embed/embed.rb @@ -0,0 +1,11 @@ +require 'ffi' + +module Hello + extend FFI::Library + ffi_lib 'target/release/libembed.dylib' + attach_function :process, [], :void +end + +Hello.process + +puts 'done!' \ No newline at end of file diff --git a/embed/pure-ruby-embed.rb b/embed/pure-ruby-embed.rb new file mode 100644 index 0000000..c9f434c --- /dev/null +++ b/embed/pure-ruby-embed.rb @@ -0,0 +1,19 @@ +threads = [] + +10.times do + threads << Thread.new do + count = 0 + + 5_000_000.times do + count += 1 + end + + count # return + end +end + +threads.each do |t| + puts "Thread finished with count=#{t.value}" +end + +puts "done!" \ No newline at end of file diff --git a/embed/src/lib.rs b/embed/src/lib.rs new file mode 100644 index 0000000..9eb7dde --- /dev/null +++ b/embed/src/lib.rs @@ -0,0 +1,19 @@ +use std::thread; + +#[no_mangle] +pub extern fn process() { + let handles: Vec<_> = (0..10).map(|_| { + thread::spawn(|| { + let mut x = 0; + for _ in 0..5_000_000 { + x += 1 + } + x // return + }) + }).collect(); + + for h in handles { + println!("Thread finished with count={}", + h.join().map_err(|_| "Could not join a thread").unwrap()); + } +} diff --git a/guessing_game/Cargo.lock b/guessing_game/Cargo.lock new file mode 100644 index 0000000..4300d47 --- /dev/null +++ b/guessing_game/Cargo.lock @@ -0,0 +1,41 @@ +[root] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "advapi32-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + diff --git a/guessing_game/Cargo.toml b/guessing_game/Cargo.toml new file mode 100644 index 0000000..434c5e9 --- /dev/null +++ b/guessing_game/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Tim Warren "] + +[dependencies] +rand = "0.3.0" diff --git a/guessing_game/src/main.rs b/guessing_game/src/main.rs new file mode 100644 index 0000000..943cb11 --- /dev/null +++ b/guessing_game/src/main.rs @@ -0,0 +1,38 @@ +extern crate rand; + +use std::io; +use std::cmp::Ordering; +use rand::Rng; + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1, 101); + + // Infinite loop + loop { + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin().read_line(&mut guess) + .ok() + .expect("Failed to read line"); + + let guess: u32 = match guess.trim().parse() { + Ok(num) => num, + Err(_) => continue, + }; + + println!("You guessed: {}", guess); + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => { + println!("You win!"); + break; + } + } + } +}