aboutsummaryrefslogtreecommitdiff
path: root/src/threader_eager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/threader_eager.c')
-rw-r--r--src/threader_eager.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/threader_eager.c b/src/threader_eager.c
new file mode 100644
index 0000000..7013518
--- /dev/null
+++ b/src/threader_eager.c
@@ -0,0 +1,162 @@
1#include <pthread.h>
2#include "threader_eager.h"
3
4typedef struct {
5 AlgList * sols;
6 pthread_mutex_t * sols_mutex;
7} ThreadData;
8
9typedef struct {
10 DfsArg * arg;
11 Solver * solver;
12 Threader * threader;
13 AlgList * starts;
14 AlgListNode ** node;
15 pthread_mutex_t * start_mutex;
16} ThreadInitData;
17
18static void append_sol(Alg *, void *);
19static void * instance_thread(void *);
20static void dispatch(DfsArg *, AlgList *, Solver *, Threader *);
21static AlgList * possible_starts(DfsArg *, Solver *);
22static int get_nsol(void *);
23
24Threader threader_eager = {
25 .append_sol = append_sol,
26 .dispatch = dispatch,
27 .get_nsol = get_nsol,
28};
29
30static void
31append_sol(Alg *alg, void *threaddata)
32{
33 ThreadData *td = (ThreadData *)threaddata;
34
35 pthread_mutex_lock(td->sols_mutex);
36 append_alg(td->sols, alg);
37 pthread_mutex_unlock(td->sols_mutex);
38}
39
40static AlgList *
41possible_starts(DfsArg *arg, Solver *solver)
42{
43 AlgList *ret = new_alglist();
44
45 if (solver->is_solved(solver->param, arg->cubedata)) {
46 if (arg->opts->min_moves == 0)
47 append_sol(new_alg(""), arg->threaddata);
48 return ret;
49 }
50
51 for (int i = 0; solver->moveset->sorted_moves[i] != NULLMOVE; i++) {
52 Move m = solver->moveset->sorted_moves[i];
53 Alg *alg = new_alg("");
54 append_move(alg, m, false);
55 append_alg(ret, alg);
56 free_alg(alg);
57
58/* TODO: check if step not final */
59 if (arg->opts->can_niss) {
60 alg = new_alg("");
61 append_move(alg, m, true);
62 append_alg(ret, alg);
63 free_alg(alg);
64 }
65 }
66
67 return ret;
68}
69
70static void *
71instance_thread(void *arg)
72{
73 ThreadInitData *tid = (ThreadInitData *)arg;
74
75 while (true) {
76 pthread_mutex_lock(tid->start_mutex);
77 AlgListNode *node = *(tid->node);
78 if (node == NULL) {
79 pthread_mutex_unlock(tid->start_mutex);
80 break;
81 }
82 *(tid->node) = (*(tid->node))->next;
83 pthread_mutex_unlock(tid->start_mutex);
84
85 void *data = tid->solver->alloc_cubedata(tid->solver->param);
86 tid->solver->copy_cubedata(
87 tid->solver->param, tid->arg->cubedata, data);
88 tid->solver->apply_alg(
89 tid->solver->param, data, node->alg);
90 bool inv = node->alg->inv[node->alg->len-1];
91 if (inv)
92 tid->solver->invert_cube(
93 tid->solver->param, data);
94
95 DfsArg newarg;
96 newarg.cubedata = data;
97 newarg.threaddata = tid->arg->threaddata;
98 newarg.opts = tid->arg->opts;
99 newarg.d = tid->arg->d;
100 newarg.niss = inv;
101 newarg.current_alg = new_alg("");
102 copy_alg(node->alg, newarg.current_alg);
103
104 dfs(&newarg, tid->solver, tid->threader);
105
106 tid->solver->free_cubedata(tid->solver->param, data);
107 free_alg(newarg.current_alg);
108 }
109
110 return NULL;
111}
112
113static void
114dispatch(DfsArg *arg, AlgList *sols, Solver *solver, Threader *threader)
115{
116 int nthreads = arg->opts->nthreads;
117 ThreadInitData tid[nthreads];
118 pthread_t t[nthreads];
119
120 pthread_mutex_t *sols_mutex = malloc(sizeof(pthread_mutex_t));
121 pthread_mutex_init(sols_mutex, NULL);
122
123 arg->threaddata = malloc(sizeof(ThreadData));
124 ThreadData *td = (ThreadData *)arg->threaddata;
125 td->sols = sols;
126 td->sols_mutex = sols_mutex;
127
128 AlgList *starts = possible_starts(arg, solver);
129 AlgListNode *node = starts->first;
130 pthread_mutex_t *start_mutex = malloc(sizeof(pthread_mutex_t));
131 pthread_mutex_init(start_mutex, NULL);
132 for (int i = 0; i < nthreads; i++) {
133 tid[i].arg = arg;
134 tid[i].solver = solver;
135 tid[i].threader = threader;
136 tid[i].starts = starts;
137 tid[i].node = &node;
138 tid[i].start_mutex = start_mutex;
139
140 pthread_create(&t[i], NULL, instance_thread, &tid[i]);
141 }
142
143 for (int i = 0; i < nthreads; i++)
144 pthread_join(t[i], NULL);
145
146 free(td);
147 free(sols_mutex);
148 free_alglist(starts);
149 free(start_mutex);
150}
151
152static int
153get_nsol(void *threaddata)
154{
155 ThreadData *td = (ThreadData *)threaddata;
156
157 pthread_mutex_lock(td->sols_mutex);
158 int n = td->sols->len;
159 pthread_mutex_unlock(td->sols_mutex);
160
161 return n;
162}

Generated with cgit - Back to sebastiano.tronto.net