sav

Sorting Algorithms Visualized
Index Commits Files Refs README LICENSE
commit cf525ad73240bbcee614e4a41a90d2494803fd4e
parent 6ce6150900d7cd6a89b7bb6b595d7eccbad2f128
Author: klewer-martin <martin.cachari@gmail.com>
Date:   Tue, 29 Mar 2022 17:34:46 -0300

Update: added a thread to run the sorting algorithm

Now the sorting algorithms runs on its own thread while the main loop
checks for events.
The sorting algorithm comunicates with main loop via the status (st)
variable, and makes the main thread update the graph, the sort thread
waits until the main loop has finished drawing the graph, then continue
execution

Diffstat:
MMakefile | 2+-
Mdrw.c | 10++++------
Mdrw.h | 2++
Msav.c | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msdl_extra.c | 19++++++-------------
Msdl_extra.h | 6+-----
Msort.c | 74--------------------------------------------------------------------------
Mutil.c | 6++++--
Mutil.h | 16++++++++++++++++
9 files changed, 115 insertions(+), 135 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
 CC := cc
 CLIBS := `sdl2-config --libs --cflags`
-CFLAGS := -lSDL2_image -lm -Wall -pedantic -ansi -std=c99 -g
+CFLAGS := -lSDL2_image -lm -Werror -Wall -pedantic -ansi -std=c99 -g -pthread
 SRCS := sav.c util.c sort.c drw.c sdl_extra.c
 OBJS := $(SRCS:.c=.o)
 
diff --git a/drw.c b/drw.c
@@ -1,10 +1,7 @@
 #include "drw.h"
 
-#define X_BORDER    40
-#define Y_BORDER    40
-#define RECT_WIDTH    5
-
-void drw_element(SDL_Renderer *rend, int x, int y, int h) {
+void
+drw_element(SDL_Renderer *rend, int x, int y, int h) {
     SDL_Rect rect;
 
     rect.x = x + X_BORDER; /* top left + x */
@@ -20,7 +17,8 @@ void drw_element(SDL_Renderer *rend, int x, int y, int h) {
     SDL_RenderDrawLine(rend, x + X_BORDER, y - Y_BORDER, x + X_BORDER, y - Y_BORDER - h);
 }
 
-void drw_element_color(SDL_Renderer *rend, int x, int y, int h, unsigned int col) {
+void
+drw_element_color(SDL_Renderer *rend, int x, int y, int h, unsigned int col) {
     SDL_Rect rect;
     unsigned char r, g, b, a;
 
diff --git a/drw.h b/drw.h
@@ -5,6 +5,8 @@
 #include <SDL2/SDL_video.h>
 #include <SDL2/SDL_image.h>
 
+#include "util.h"
+
 void drw_element(SDL_Renderer *rend, int x, int y, int h);
 void drw_element_color(SDL_Renderer *rend, int x, int y, int h, unsigned int col);
 
diff --git a/sav.c b/sav.c
@@ -17,21 +17,39 @@
 #define SEL_COLOR    0x00FF0000 // RGBA
 #define CMP_COLOR    0x00FFFF00
 
-#define ARR_LEN        120
-#define ARR_MAX        500
-
-#define RECT_WIDTH    5
-
-int arr[ARR_LEN];
+typedef struct {
+    int *v;
+    size_t len;
+} Arr;
+
+/* Maybe in a future */
+/* typedef struct {
+    int sel, cmp;
+    status_t st;
+    Arr *arr;
+    SDL_Renderer *rend;
+    SDL_Window *win;
+} Graph;
+*/
+
+/* variables */
 SDL_Renderer *rend;
 SDL_Window *win;
+Arr *arr = NULL;
+
 size_t sel, cmp;
 status_t st;
 
-void update_array_graph(SDL_Renderer *rend, SDL_Window *win);
-void insertion_sort(int *arr, size_t len);
+/* functions declarations */
+void update_array_graph(SDL_Renderer *rend, SDL_Window *win, Arr *arr);
+void wait_main_thread(void);
+void *routine_wrapper(void *arg);
+void insertion_sort(Arr *arr);
 
-void update_array_graph(SDL_Renderer *rend, SDL_Window *win) {
+
+/* functions definitions */
+void
+update_array_graph(SDL_Renderer *rend, SDL_Window *win, Arr *arr) {
     int x, w, h;
 
     SDL_GetWindowSize(win, &w, &h);
@@ -40,62 +58,91 @@ void update_array_graph(SDL_Renderer *rend, SDL_Window *win) {
     SDL_RenderClear(rend);
 
     size_t i;
-    for(i = x = 0; i < ARR_LEN; i++, x += RECT_WIDTH) {
-        if(i == sel) drw_element_color(rend, x, h, arr[i], SEL_COLOR);
-        else if(i == cmp) drw_element_color(rend, x, h, arr[i], CMP_COLOR);
-        else drw_element(rend, x, h, arr[i]);
+    for(i = x = 0; i < arr->len; i++, x += RECT_WIDTH) {
+        if(i == sel) drw_element_color(rend, x, h, arr->v[i], SEL_COLOR);
+        else if(i == cmp) drw_element_color(rend, x, h, arr->v[i], CMP_COLOR);
+        else drw_element(rend, x, h, arr->v[i]);
     }
 
     SDL_RenderPresent(rend);
 }
 
-void insertion_sort(int *arr, size_t len) {
+void
+wait_main_thread(void) {
+    if(st != STOP) st = UPDATE;
+
+    /* wait 'til main thread changes st value to RUN */
+    while(st == UPDATE);
+}
+
+void
+insertion_sort(Arr *arr) {
     int key;
     size_t i, j;
 
-    for(i = 1, st = RUN; i < len; i++) {
-        key = arr[i];
+    for(i = 1; i < arr->len; i++) {
+        key = arr->v[i];
         j = i - 1;
-        while((j >= 0) && (arr[j] > key)) {
-            arr[j + 1] = arr[j];
+        while((j >= 0) && (arr->v[j] > key)) {
+            arr->v[j + 1] = arr->v[j];
             j = j - 1;
             sel = i;
             cmp = j;
-            update_array_graph(rend, win);
-            check_events(&st);
+
+            /* wait 'til main thread updates graphics */
+            wait_main_thread();
             if(st == STOP) break;
         }
-        arr[j + 1] = key;
+        arr->v[j + 1] = key;
         sel = i;
         cmp = j;
-        update_array_graph(rend, win);
-        check_events(&st);
+        /* wait 'til main thread updates graphics */
+        wait_main_thread();
         if(st == STOP) break;
     }
 }
 
-int main (void) {
-    size_t i, len;
+void *
+routine_wrapper(void *arg) {
+    Arr *arr = (Arr *)arg;
+
+    insertion_sort(arr);
+
+    return NULL;
+}
+
+int
+main (void) {
+    size_t i;
+    pthread_t p1;
 
-    len = ARR_LEN;
     sel = cmp = 0;
 
     setup(&win, &rend);
 
+    arr = (Arr *)malloc(sizeof(Arr));
+    arr->v = (int *)malloc(sizeof(int) * ARR_LEN);
+    arr->len = ARR_LEN;
+
     /* create a random array */
     srand((unsigned int)time(NULL));
-    for(i = 0; i < len; i++)
-        while(!(arr[i] = rand() % ARR_MAX))
-            arr[i] = (rand() % ARR_MAX);
+    for(i = 0; i < arr->len; i++)
+        while(!(arr->v[i] = rand() % ARR_MAX))
 
-    /* main loop */
     st = RUN;
+
+    pthread_create(&p1, NULL, &routine_wrapper, (void *)arr);
+
+    /* main loop */
     while(st != STOP) {
-        check_events(&st);
-        update_array_graph(rend, win);
-        insertion_sort(arr, len);
+        check_events(&st); 
+        if(st == UPDATE) {
+            update_array_graph(rend, win, arr);
+            st = RUN;
+        }
     }
-    
+
+    pthread_join(p1, NULL);
     cleanup(win, rend);
     return 0;
 }
diff --git a/sdl_extra.c b/sdl_extra.c
@@ -1,17 +1,9 @@
 #include "sdl_extra.h"
-#include "util.h"
 
 #define WINDOW_TITLE "SAV - Sorting Algorithms Visualized"
 
-#define ARR_LEN        120
-#define ARR_MAX        500
-
-#define X_BORDER    40
-#define Y_BORDER    40
-#define RECT_WIDTH    5
-#define TOP_BORDER    50
-
-void check_events(status_t *status) {
+void
+check_events(status_t *status) {
     SDL_Event event;
     while (SDL_PollEvent(&event)) {
         switch(event.type) {
@@ -35,7 +27,8 @@ void check_events(status_t *status) {
     }
 }
 
-void setup(SDL_Window **win, SDL_Renderer **rend) {
+void
+setup(SDL_Window **win, SDL_Renderer **rend) {
     int min_w, min_h;
 
     SDL_Init(SDL_INIT_VIDEO);
@@ -66,9 +59,9 @@ void setup(SDL_Window **win, SDL_Renderer **rend) {
     SDL_SetWindowMaximumSize(*win, min_w, min_h);
 }
 
-void cleanup(SDL_Window *win, SDL_Renderer *rend) {
+void
+cleanup(SDL_Window *win, SDL_Renderer *rend) {
     SDL_DestroyRenderer(rend);
     SDL_DestroyWindow(win);
     SDL_Quit();
 }
-
diff --git a/sdl_extra.h b/sdl_extra.h
@@ -13,11 +13,7 @@
 /*     void (*sort)(int *arr, size_t len); */
 /* } Sav; */
 
-typedef enum {
-    RUN,
-    PAUSE,
-    STOP
-} status_t;
+#include "util.h"
 
 void check_events(status_t *status);
 void setup(SDL_Window **win, SDL_Renderer **rend);
diff --git a/sort.c b/sort.c
@@ -4,12 +4,6 @@
 #include "sort.h"
 #include "util.h"
 
-typedef enum {
-    RUN,
-    PAUSE,
-    STOP
-} status_t;
-
 int bubble_sort(int *arr, size_t len) {
     if(arr == NULL) return 1;
 
@@ -37,71 +31,3 @@ int bubble_sort(int *arr, size_t len) {
 
     return 1;
 }
-
-/* int insertion_sort(int *arr, size_t len) { */
-/*     static size_t i = 1; */
-/*     int j; */
-
-/*     int key; */
-
-/*     if(i < len) { */
-/*         key = arr[i]; */
-/*         j = i - 1; */
-
-/*         while((j >= 0) && (arr[j] > key)) { */
-/*             arr[j + 1] = arr[j]; */
-/*             j = j - 1; */
-/*         } */
-
-/*         arr[j + 1] = key; */
-/*         i++; */
-/*         return 1; */
-/*     } */
-
-/*     return 0; */
-/* } */
-
-/* void insertion_sort(int *arr, size_t len) { */
-    /* int key; */
-    /* size_t i, j; */
-
-    /* extern status_t status; */
-    /* extern size_t sel, cmp; */
-    /* bool sorted = false; */
-    /* extern bool update; */
-
-    /* /1* if((sorted == false) && (status == RUN)) { *1/ */
-    /* while((status == RUN) && (sorted != true)) { */
-    /*     if(status != PAUSE) { */
-    /*         for(i = 1; i < len; i++) { */
-    /*             key = arr[i]; */
-    /*             j = i - 1; */
-    /*             while((j >= 0) && (arr[j] > key)) { */
-    /*                 arr[j + 1] = arr[j]; */
-    /*                 j = j - 1; */
-    /*                 sel = i; */
-    /*                 cmp = j; */
-    /*                 /1* update_array_graph(rend, win); *1/ */
-    /*                 /1* SDL_Delay(speed); *1/ */
-    /*                 /1* if(status == PAUSED) goto end_sort; *1/ */
-    /*             } */
-    /*             arr[j + 1] = key; */
-    /*             sel = i; */
-    /*             cmp = j; */
-    /*             /1* if(status == PAUSED) goto end_sort; *1/ */
-    /*             /1* update_array_graph(rend, win); *1/ */
-    /*             /1* SDL_Delay(speed); *1/ */
-    /*         } */
-    /*     sel = cmp = i; */ 
-    /*     update = true; */
-    /*     /1* goto end_sort; *1/ */
-    /*     /1* update_array_graph(rend, win); *1/ */
-    /*     /1* SDL_Delay(speed); *1/ */
-    /*     /1* sorted = true; *1/ */
-    /*     } */
-    /* } */
-    /* update_array_graph(rend, win); */
-    /* SDL_Delay(speed); */
-    /* return 0; */
-/* } */
-
diff --git a/util.c b/util.c
@@ -1,11 +1,13 @@
 #include "util.h"
 
-void end(const char *msg) {
+void
+end(const char *msg) {
     fprintf(stderr, "%s\n", msg);
     exit(1);
 }
 
-void swap(int *a, int *b)
+void
+swap(int *a, int *b)
 {
     int tmp;
     tmp = (*a);
diff --git a/util.h b/util.h
@@ -4,6 +4,22 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#define ARR_LEN        120
+#define ARR_MAX        500
+
+#define X_BORDER    40
+#define Y_BORDER    40
+#define TOP_BORDER    50
+
+#define RECT_WIDTH    6    
+
+typedef enum {
+    RUN,
+    PAUSE,
+    UPDATE,
+    STOP
+} status_t;
+
 void end(const char *msg);
 void swap(int *a, int *b);