| ... | ... |
@@ -11,20 +11,21 @@ INSTALL=install |
| 11 | 11 |
INSTALL_PROGRAM=$(INSTALL) |
| 12 | 12 |
INSTALL_DATA=${INSTALL} -m 644
|
| 13 | 13 |
|
| 14 |
+LIBS=-lpthread |
|
| 14 | 15 |
OBJECTS=src/fzy.o src/match.o src/tty.o src/choices.o src/options.o src/tty_interface.o |
| 15 | 16 |
TESTOBJECTS=test/fzytest.c src/match.o src/choices.o |
| 16 | 17 |
|
| 17 | 18 |
all: fzy |
| 18 | 19 |
|
| 19 | 20 |
test/fzytest: $(TESTOBJECTS) |
| 20 |
- $(CC) $(CFLAGS) $(CCFLAGS) -Isrc -o $@ $(TESTOBJECTS) |
|
| 21 |
+ $(CC) $(CFLAGS) $(CCFLAGS) -Isrc -o $@ $(TESTOBJECTS) $(LIBS) |
|
| 21 | 22 |
|
| 22 | 23 |
test: check |
| 23 | 24 |
check: test/fzytest |
| 24 | 25 |
$(DEBUGGER) ./test/fzytest |
| 25 | 26 |
|
| 26 | 27 |
fzy: $(OBJECTS) |
| 27 |
- $(CC) $(CFLAGS) $(CCFLAGS) -o $@ $(OBJECTS) |
|
| 28 |
+ $(CC) $(CFLAGS) $(CCFLAGS) -o $@ $(OBJECTS) $(LIBS) |
|
| 28 | 29 |
|
| 29 | 30 |
%.o: %.c config.h |
| 30 | 31 |
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< |
| ... | ... |
@@ -134,23 +134,77 @@ size_t choices_available(choices_t *c) {
|
| 134 | 134 |
return c->available; |
| 135 | 135 |
} |
| 136 | 136 |
|
| 137 |
+#include <pthread.h> |
|
| 138 |
+ |
|
| 139 |
+struct worker {
|
|
| 140 |
+ pthread_t thread_id; |
|
| 141 |
+ choices_t *choices; |
|
| 142 |
+ const char *search; |
|
| 143 |
+ size_t worker_count; |
|
| 144 |
+ size_t worker_num; |
|
| 145 |
+ struct scored_result *results; |
|
| 146 |
+ size_t available; |
|
| 147 |
+}; |
|
| 148 |
+ |
|
| 149 |
+static void *choices_search_worker(void *data) {
|
|
| 150 |
+ struct worker *w = (struct worker *)data; |
|
| 151 |
+ const choices_t *c = w->choices; |
|
| 152 |
+ |
|
| 153 |
+ size_t start = (w->worker_num) * c->size / w->worker_count; |
|
| 154 |
+ size_t end = (w->worker_num + 1) * c->size / w->worker_count; |
|
| 155 |
+ |
|
| 156 |
+ for(size_t i = start; i < end; i++) {
|
|
| 157 |
+ if (has_match(w->search, c->strings[i])) {
|
|
| 158 |
+ w->results[w->available].str = c->strings[i]; |
|
| 159 |
+ w->results[w->available].score = match(w->search, c->strings[i]); |
|
| 160 |
+ w->available++; |
|
| 161 |
+ } |
|
| 162 |
+ } |
|
| 163 |
+ |
|
| 164 |
+ return w; |
|
| 165 |
+} |
|
| 166 |
+ |
|
| 137 | 167 |
void choices_search(choices_t *c, const char *search) {
|
| 138 | 168 |
choices_reset_search(c); |
| 139 | 169 |
|
| 170 |
+ /* allocate storage for our results */ |
|
| 140 | 171 |
c->results = malloc(c->size * sizeof(struct scored_result)); |
| 141 | 172 |
if (!c->results) {
|
| 142 | 173 |
fprintf(stderr, "Error: Can't allocate memory\n"); |
| 143 | 174 |
abort(); |
| 144 | 175 |
} |
| 145 | 176 |
|
| 146 |
- for (size_t i = 0; i < c->size; i++) {
|
|
| 147 |
- if (has_match(search, c->strings[i])) {
|
|
| 148 |
- c->results[c->available].str = c->strings[i]; |
|
| 149 |
- c->results[c->available].score = match(search, c->strings[i]); |
|
| 150 |
- c->available++; |
|
| 177 |
+ int worker_count = 8; |
|
| 178 |
+ struct worker *workers = calloc(worker_count, sizeof(struct worker)); |
|
| 179 |
+ for (int i = 0; i < worker_count; i++) {
|
|
| 180 |
+ workers[i].choices = c; |
|
| 181 |
+ workers[i].search = search; |
|
| 182 |
+ workers[i].worker_count = worker_count; |
|
| 183 |
+ workers[i].worker_num = i; |
|
| 184 |
+ workers[i].results = malloc(c->size * sizeof(struct scored_result)); /* FIXME: This is overkill */ |
|
| 185 |
+ int ret = pthread_create(&workers[i].thread_id, NULL, &choices_search_worker, &workers[i]); |
|
| 186 |
+ if (ret != 0) {
|
|
| 187 |
+ perror("pthread_create");
|
|
| 188 |
+ exit(EXIT_FAILURE); |
|
| 151 | 189 |
} |
| 152 | 190 |
} |
| 153 | 191 |
|
| 192 |
+ for (int i = 0; i < worker_count; i++) {
|
|
| 193 |
+ struct worker *w = &workers[i]; |
|
| 194 |
+ |
|
| 195 |
+ int ret = pthread_join(w->thread_id, NULL); |
|
| 196 |
+ if (ret != 0) {
|
|
| 197 |
+ perror("pthread_join");
|
|
| 198 |
+ exit(EXIT_FAILURE); |
|
| 199 |
+ } |
|
| 200 |
+ |
|
| 201 |
+ memcpy(&c->results[c->available], w->results, w->available * sizeof(struct scored_result)); |
|
| 202 |
+ c->available += w->available; |
|
| 203 |
+ |
|
| 204 |
+ free(w->results); |
|
| 205 |
+ } |
|
| 206 |
+ free(workers); |
|
| 207 |
+ |
|
| 154 | 208 |
if(*search) {
|
| 155 | 209 |
qsort(c->results, c->available, sizeof(struct scored_result), cmpchoice); |
| 156 | 210 |
} |