commit 54fd25077b19ed9ce6d4c5a42b54bf8ce0bc0ff7
parent 3f4956957b32cde2b5e303345cd94929252395ae
Author: bsandro <email@bsandro.tech>
Date: Wed, 6 Dec 2023 21:52:30 +0200
day 05 p2 with lots of abusing native C11 and Ryzen power
Diffstat:
3 files changed, 99 insertions(+), 9 deletions(-)
diff --git a/day05/Makefile b/day05/Makefile
@@ -2,8 +2,8 @@ NAME=$(shell basename ${PWD})
SRC=$(wildcard *.c)
DEPS:=$(wildcard *.h)
OBJ:=$(SRC:.c=.o)
-CFLAGS=-O2 -std=c11 -Werror -Wall -Wextra -I. -I../common
-LDFLAGS=-lc
+CFLAGS=-O2 -std=c11 -pthread -Werror -Wall -Wextra -I. -I../common
+LDFLAGS=-lc -pthread
all: $(NAME)
diff --git a/day05/main.c b/day05/main.c
@@ -1,6 +1,9 @@
#include <stdio.h>
#include <time.h>
#include <string.h>
+#include <threads.h>
+#include <stdatomic.h>
+#include <stdlib.h>
void puzzle(const char *filename, long long *res1, long long *res2);
//void puzzle_test(const char *filename, long long *res1, long long *res2);
@@ -26,5 +29,7 @@ int main(int argc, char *argv[]) {
double elapsed = clock() - time_start;
printf("Elapsed: %f\n", elapsed / CLOCKS_PER_SEC);
+ thrd_exit(EXIT_SUCCESS);
+
return 0;
}
diff --git a/day05/puzzle.c b/day05/puzzle.c
@@ -9,6 +9,8 @@
#include <assert.h>
#include <stdbool.h>
#include <inttypes.h>
+#include <stdatomic.h>
+#include <threads.h>
#define STR_LEN 2048
@@ -86,6 +88,40 @@ void fill_range(Range *r, uint64_t dst_start, uint64_t src_start, uint64_t len)
r->dst[1] = dst_start + len;
}
+typedef struct RunArgs {
+ Range *ranges;
+ uint64_t seed1;
+ uint64_t seed2;
+ mtx_t *mutex;
+ long long *result2;
+} RunArgs;
+
+int run_calc(void *a) {
+ RunArgs *ra = (RunArgs *)a;
+ uint64_t seed1 = ra->seed1;
+ uint64_t seed2 = ra->seed2;
+ Range *ranges = ra->ranges;
+ uint64_t res2 = 0;
+ //printf("seed from %" PRIu64 " of count %" PRIu64 "\n", seed1, seed2);
+
+ // brain damage
+ for (uint64_t i=seed1; i<seed1+seed2; ++i) {
+ uint64_t loc = calc_loc(ranges, i);
+ if (res2==0||loc<res2) res2 = loc;
+ }
+ //printf("res2: %" PRIu64 "\n", res2);
+ if (mtx_lock(ra->mutex)!=thrd_success) {
+ printf("mutex lock error\n");
+ //thrd_exit(EXIT_FAILURE);
+ }
+ if (*ra->result2==-1||res2<(uint64_t)*ra->result2) *ra->result2 = res2;
+ if (mtx_unlock(ra->mutex)!=thrd_success) {
+ printf("mutex unlock error\n");
+ //thrd_exit(EXIT_FAILURE);
+ }
+ return 0;
+}
+
void puzzle(const char *filename, long long *result1, long long *result2) {
FILE *infile = fopen(filename, "r");
if (infile == NULL) {
@@ -96,8 +132,6 @@ void puzzle(const char *filename, long long *result1, long long *result2) {
char buf[STR_LEN] = {0};
unsigned int line_num = 0;
- *result2 = 0;
-
Number *seeds = NULL;
Number *seeds_last = NULL;
@@ -146,14 +180,65 @@ void puzzle(const char *filename, long long *result1, long long *result2) {
}
//print_ranges(ranges);
- Number *s = seeds;
- while (s!=NULL) {
- uint64_t loc = calc_loc(ranges, s->value);
+ Number *s1 = seeds;
+ while (s1!=NULL) {
+ uint64_t loc = calc_loc(ranges, s1->value);
if (*result1==-1||loc<(uint64_t)*result1) *result1 = loc;
- //printf("seed %" PRIu64 " location: %" PRIu64 "\n", s->value, loc);
- s = s->next;
+ //printf("seed %" PRIu64 " location: %" PRIu64 "\n", s1->value, loc);
+ s1 = s1->next;
+ }
+
+ Number *s2 = seeds;
+ thrd_t threads[10] = {0};
+ int thread_id = 0;
+ static mtx_t mutex;
+ if (mtx_init(&mutex, mtx_plain)!=thrd_success) {
+ printf("error initing mutex\n");
+ thrd_exit(EXIT_FAILURE);
+ }
+ while (s2!=NULL) {
+ uint64_t seed1 = s2->value;
+ uint64_t seed2 = 0;
+ if (s2->next!=NULL) {
+ seed2 = s2->next->value;
+ s2 = s2->next->next;
+ }
+ //printf("seed from %" PRIu64 " of count %" PRIu64 "\n", seed1, seed2);
+
+ // brain damage
+ /*for (uint64_t i=seed1; i<seed1+seed2; ++i) {
+ uint64_t loc = calc_loc(ranges, i);
+ if (*result2==-1||loc<(uint64_t)*result2) *result2 = loc;
+ }*/
+ RunArgs *a = malloc(sizeof(RunArgs));
+ a->ranges = ranges;
+ a->seed1 = seed1;
+ a->seed2 = seed2;
+ a->result2 = result2;
+ a->mutex = &mutex;
+ int t_res=thrd_create(&threads[thread_id], run_calc, (void *)a);
+ if (t_res!=thrd_success) {
+ printf("thrd_create %d error %d\n", thread_id, t_res);
+ }
+ ++thread_id;
+ }
+
+ for (int i=0; i<thread_id; ++i) {
+ //printf("waiting for t %d\n", i);
+ int t_out = 0;
+ int t_res = thrd_join(threads[i], &t_out);
+ if (t_res!=thrd_success) {
+ printf("error joining thread %d: %d (out %d)\n", i, t_res, t_out);
+ //thrd_exit(EXIT_FAILURE);
+ }
+ //printf("end waiting for t %d\n", i);
}
// mutiny! ignoring feof/ferror.
fclose(infile);
+
+ //printf("res1: %lld\n", *result1);
+ //printf("res2: %lld\n", *result2);
+
+ //thrd_exit(EXIT_SUCCESS);
}