[gnome-sudoku/multithread_printing] Start multiple threads in the async method for puzzle generation
- From: Parin Porecha <parinporecha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-sudoku/multithread_printing] Start multiple threads in the async method for puzzle generation
- Date: Fri, 15 Aug 2014 09:50:45 +0000 (UTC)
commit 0b7653bfa405760a04c37f97fe4c1c9447378ae8
Author: Parin Porecha <parinporecha gmail com>
Date: Fri Aug 15 11:49:00 2014 +0200
Start multiple threads in the async method for puzzle generation
Also remove spinner from new game screen
data/gnome-sudoku.ui | 5 ---
data/print-games.ui | 15 ++++++----
lib/sudoku-generator.vala | 71 ++++++++++++++++++++++++++++++++++++--------
src/gnome-sudoku.vala | 7 ----
src/sudoku-printer.vala | 6 ++--
5 files changed, 70 insertions(+), 34 deletions(-)
---
diff --git a/data/gnome-sudoku.ui b/data/gnome-sudoku.ui
index 1893988..d85f406 100644
--- a/data/gnome-sudoku.ui
+++ b/data/gnome-sudoku.ui
@@ -154,11 +154,6 @@
<property name="position">3</property>
</packing>
</child>
- <child>
- <object class="GtkSpinner" id="start_spinner">
- <property name="visible">True</property>
- </object>
- </child>
</object> <!-- End of start_box -->
<packing>
<property name="name">start_box</property>
diff --git a/data/print-games.ui b/data/print-games.ui
index 44f9533..41815ed 100644
--- a/data/print-games.ui
+++ b/data/print-games.ui
@@ -24,12 +24,6 @@
<property name="can_focus">False</property>
<property name="show-close-button">False</property>
<child>
- <object class="GtkSpinner" id="spinner">
- <property name="halign">center</property>
- <property name="visible">False</property>
- </object>
- </child>
- <child>
<object class="GtkButton" id="okbutton1">
<property name="label" translatable="yes">_Print</property>
<property name="visible">True</property>
@@ -60,6 +54,15 @@
<property name="pack_type">start</property>
</packing>
</child>
+ <child>
+ <object class="GtkSpinner" id="spinner">
+ <property name="valign">center</property>
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
</object>
</child>
<child internal-child="vbox">
diff --git a/lib/sudoku-generator.vala b/lib/sudoku-generator.vala
index c67f4e5..cb34444 100644
--- a/lib/sudoku-generator.vala
+++ b/lib/sudoku-generator.vala
@@ -1,5 +1,7 @@
/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+using Gee;
+
public class SudokuGenerator : Object
{
private SudokuGenerator () {
@@ -24,23 +26,38 @@ public class SudokuGenerator : Object
public async static SudokuBoard[] generate_boards_async (int nboards, DifficultyCategory category)
throws ThreadError
{
- SourceFunc callback = generate_boards_async.callback;
+ var boards_list = new ArrayList<SudokuBoard> ();
var boards = new SudokuBoard[nboards];
- // Hold reference to closure to keep it from being freed whilst
- // thread is active.
- ThreadFunc<void*> generate = () => {
- for (var i = 0; i < nboards; i++)
- boards[i] = generate_board (category);
+// var sysinfo = GLibtop.glibtop_sysinfo.get_sysinfo ();
+// stdout.printf ("ncpus = %d\n", sysinfo.ncpu);
+ var ncpu = 4;
+ var nthreads = int.min (ncpu, nboards);
+ var base_nsudokus_each = nboards / nthreads;
+ var remainder = nboards % nthreads;
+ var nsudokus_per_thread = base_nsudokus_each;
+
+ stdout.printf ("no. of threads = %d\n", nthreads);
+
+ for (var i = 0; i < nthreads; i++)
+ {
+ if (i > (nthreads - remainder - 1))
+ nsudokus_per_thread = base_nsudokus_each + 1;
+ var gen_thread = new GeneratorThread (nsudokus_per_thread, category, ref boards_list,
generate_boards_async.callback, i);
+ Thread<int> thread = new Thread<int> ("Generator thread", gen_thread.run);
+
+ // Relinquish the CPU, so that the generated thread can run
+ yield;
- // Schedule callback
- Idle.add((owned) callback);
- return null;
- };
- new Thread<void*>("Generator thread", generate);
+ stdout.printf ("waiting for #%d to join\n", i);
+ var result = thread.join ();
+ stdout.printf ("Thread #%d exited\n", result);
+ }
+
+ stdout.printf ("boards list size = %d\n", boards_list.size);
+ for (var i = 0; i < boards_list.size; i++)
+ boards[i] = boards_list[i];
- // Wait for background thread to schedule our callback
- yield;
return boards;
}
@@ -61,3 +78,31 @@ public class SudokuGenerator : Object
return QQwing.get_version ();
}
}
+
+public class GeneratorThread : Object
+{
+ private int nsudokus;
+ private DifficultyCategory level;
+ private int id;
+ private ArrayList<SudokuBoard> boards_list;
+ private SourceFunc callback;
+
+ public GeneratorThread (int nsudokus, DifficultyCategory level, ref ArrayList<SudokuBoard> boards_list,
SourceFunc callback, int id)
+ {
+ this.nsudokus = nsudokus;
+ this.level = level;
+ this.id = id;
+ this.boards_list = boards_list;
+ this.callback = callback;
+ }
+
+ public int run ()
+ {
+ stdout.printf ("generating %d puzzles\n", nsudokus);
+ for (var i = 0; i < nsudokus; i++)
+ boards_list.add (SudokuGenerator.generate_board (level));
+
+ Idle.add((owned) callback);
+ return id;
+ }
+}
diff --git a/src/gnome-sudoku.vala b/src/gnome-sudoku.vala
index 189a2c3..fb60af5 100644
--- a/src/gnome-sudoku.vala
+++ b/src/gnome-sudoku.vala
@@ -297,14 +297,7 @@ public class Sudoku : Gtk.Application
SudokuGenerator.generate_boards_async.begin (1, selected_difficulty, (obj, res) => {
try {
- var spinner = builder.get_object ("start_spinner") as Spinner;
- spinner.active = true;
- spinner.show ();
- spinner.start ();
-
var gen_boards = SudokuGenerator.generate_boards_async.end (res);
-
- spinner.stop ();
start_game (gen_boards[0]);
} catch (ThreadError e) {
error ("Thread error: %s", e.message);
diff --git a/src/sudoku-printer.vala b/src/sudoku-printer.vala
index c77dacb..89b6fab 100644
--- a/src/sudoku-printer.vala
+++ b/src/sudoku-printer.vala
@@ -327,6 +327,9 @@ public class GamePrinter: GLib.Object
try {
var boards = SudokuGenerator.generate_boards_async.end(res);
+ spinner.stop ();
+ spinner.hide ();
+
SudokuPrinter printer = new SudokuPrinter (boards, ref window);
PrintOperationResult result = printer.print_sudoku ();
if (result == PrintOperationResult.APPLY)
@@ -335,10 +338,7 @@ public class GamePrinter: GLib.Object
foreach (SudokuBoard board in boards)
saver.add_game_to_finished (new SudokuGame (board));
}
-
boards_list = null;
- spinner.stop ();
- spinner.hide ();
} catch (ThreadError e) {
error ("Thread error: %s\n", e.message);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]