From 9f0fb6f24b8da085cfbc8612067ac0370b71ebc4 Mon Sep 17 00:00:00 2001
From: Tavian Barnes <tavianator@gmail.com>
Date: Fri, 26 Jun 2009 15:51:17 +0000
Subject: Remove thread-synchronicity from canvases.

---
 libdimension/canvas.c           | 110 ++++------------------------------------
 libdimension/dimension/canvas.h |  16 ++----
 2 files changed, 13 insertions(+), 113 deletions(-)

(limited to 'libdimension')

diff --git a/libdimension/canvas.c b/libdimension/canvas.c
index 13b1e9e..c2bd5cf 100644
--- a/libdimension/canvas.c
+++ b/libdimension/canvas.c
@@ -22,12 +22,10 @@
 #include <pthread.h>
 #include <stdlib.h> /* For malloc(), free() */
 
-/* Allocate a new canvas, of width x and height y.  If any intermediary step
-   fails, free all acquired memory to avoid leaks. */
+/* Allocate a new canvas, of width x and height y */
 dmnsn_canvas *
 dmnsn_new_canvas(unsigned int x, unsigned int y)
 {
-  unsigned int i, j, k, l;
   /* Allocate the dmnsn_canvas struct */
   dmnsn_canvas *canvas = malloc(sizeof(dmnsn_canvas));
 
@@ -42,47 +40,6 @@ dmnsn_new_canvas(unsigned int x, unsigned int y)
       free(canvas);
       return NULL;
     }
-
-    /* Allocate the rwlocks */
-    canvas->rwlocks = malloc(sizeof(pthread_rwlock_t)*x*y);
-    if (!canvas->rwlocks) {
-      free(canvas->pixels);
-      free(canvas);
-      return NULL;
-    }
-
-    /* Initialize the rwlocks */
-    for (i = 0; i < x; ++i) {
-      for (j = 0; j < y; ++j) {
-        if (pthread_rwlock_init(&canvas->rwlocks[j*x + i], NULL) != 0) {
-          /* pthread_rwlock_init failed.  Destroy the locks we've already made,
-             free the canvas, and return NULL.  We leak memory if destruction
-             fails (i.e. someone is somehow using an rwlock already). */
-
-          for (l = 0; l < j; ++l) {
-            for (k = 0; k < x; ++k) {
-              if (pthread_rwlock_destroy(&canvas->rwlocks[l*x + k]) != 0) {
-                /* Low severity, because leaked locks won't actually hurt us */
-                dmnsn_error(DMNSN_SEVERITY_LOW,
-                            "Leaking rwlocks in failed allocation.");
-              }
-            }
-          }
-
-          for (k = 0; k < i; ++k) {
-            if (pthread_rwlock_destroy(&canvas->rwlocks[j*x + k]) != 0) {
-              dmnsn_error(DMNSN_SEVERITY_LOW,
-                          "Leaking rwlocks in failed allocation.");
-            }
-          }
-
-          free(canvas->rwlocks);
-          free(canvas->pixels);
-          free(canvas);
-          return NULL;
-        }
-      }
-    }
   }
 
   return canvas;
@@ -92,78 +49,31 @@ dmnsn_new_canvas(unsigned int x, unsigned int y)
 void
 dmnsn_delete_canvas(dmnsn_canvas *canvas)
 {
-  unsigned int i, j;
-
   if (canvas) {
-    /* Destroy the rwlocks */
-    for (i = 0; i < canvas->x; ++i) {
-      for (j = 0; j < canvas->y; ++j) {
-        if (pthread_rwlock_destroy(&canvas->rwlocks[j*canvas->x + i]) != 0) {
-              dmnsn_error(DMNSN_SEVERITY_LOW,
-                          "Leaking rwlocks in deallocation.");
-        }
-      }
-    }
-
-    /* Free the locks, pixels, and canvas */
-    free(canvas->rwlocks);
+    /* Free the pixels and canvas */
     free(canvas->pixels);
     free(canvas);
   }
 }
 
-/* Get a pixel at (x,y) thread-safely, using dmnsn_rdlock_pixel. */
+/* Get a pixel at (x,y) */
 dmnsn_color
 dmnsn_get_pixel(const dmnsn_canvas *canvas, unsigned int x, unsigned int y)
 {
-  dmnsn_color color;
-  dmnsn_rdlock_pixel(canvas, x, y);
-    color = canvas->pixels[y*canvas->x + x];
-  dmnsn_unlock_pixel(canvas, x, y);
-  return color;
+  return canvas->pixels[y*canvas->x + x];
 }
 
-/* Set a pixel at (x,y) thread-safely, using dmnsn_wrlock_pixel. */
+/* Set a pixel at (x,y) */
 void
 dmnsn_set_pixel(dmnsn_canvas *canvas,
                 unsigned int x, unsigned int y, dmnsn_color color)
 {
-  dmnsn_wrlock_pixel(canvas, x, y);
-    canvas->pixels[y*canvas->x + x] = color;
-  dmnsn_unlock_pixel(canvas, x, y);
+  canvas->pixels[y*canvas->x + x] = color;
 }
 
-/* Acquire a read-lock for a pixel */
-void
-dmnsn_rdlock_pixel(const dmnsn_canvas *canvas, unsigned int x, unsigned int y)
-{
-  if (pthread_rwlock_rdlock(&canvas->rwlocks[y*canvas->x + x]) != 0) {
-    /* Medium severity, because undefined behaviour is pretty likely if our
-       reads and writes aren't synced */
-    dmnsn_error(DMNSN_SEVERITY_MEDIUM,
-                "Couldn't acquire read-lock for pixel.");
-  }
-}
-
-/* Acquire a write-lock for a pixel */
-void
-dmnsn_wrlock_pixel(dmnsn_canvas *canvas, unsigned int x, unsigned int y)
+/* Point to the pixel at (x,y) */
+dmnsn_color *
+dmnsn_pixel_at(dmnsn_canvas *canvas, unsigned int x, unsigned int y)
 {
-  if (pthread_rwlock_wrlock(&canvas->rwlocks[y*canvas->x + x]) != 0) {
-    /* Medium severity, because undefined behaviour is pretty likely if our
-       reads and writes aren't synced */
-    dmnsn_error(DMNSN_SEVERITY_MEDIUM,
-                "Couldn't acquire write-lock for pixel.");
-  }
-}
-
-/* Unlock a pixel */
-void
-dmnsn_unlock_pixel(const dmnsn_canvas *canvas, unsigned int x, unsigned int y)
-{
-  if (pthread_rwlock_unlock(&canvas->rwlocks[y*canvas->x + x]) != 0) {
-    /* Medium severity, because if the pixel is locked, we're likely to hang
-       the next time we try to read or write it */
-    dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't unlock pixel.");
-  }
+  return canvas->pixels + y*canvas->x + x;
 }
diff --git a/libdimension/dimension/canvas.h b/libdimension/dimension/canvas.h
index 50cc612..cd414a9 100644
--- a/libdimension/dimension/canvas.h
+++ b/libdimension/dimension/canvas.h
@@ -25,8 +25,6 @@
 #ifndef DIMENSION_CANVAS_H
 #define DIMENSION_CANVAS_H
 
-#include <pthread.h>
-
 typedef struct {
   unsigned int x, y;
 
@@ -35,26 +33,18 @@ typedef struct {
    * at (a,b) is accessible as pixels[b*x + a].
    */
   dmnsn_color *pixels;
-
-  /* Read-write locks for each pixel */
-  pthread_rwlock_t *rwlocks;
 } dmnsn_canvas;
 
 /* Allocate and free a canvas */
 dmnsn_canvas *dmnsn_new_canvas(unsigned int x, unsigned int y);
 void dmnsn_delete_canvas(dmnsn_canvas *canvas);
 
-/* These handle the rwlocks correctly */
+/* Pixel accessors */
 dmnsn_color dmnsn_get_pixel(const dmnsn_canvas *canvas,
                             unsigned int x, unsigned int y);
 void dmnsn_set_pixel(dmnsn_canvas *canvas,
                      unsigned int x, unsigned int y, dmnsn_color color);
-
-/* Manual locking */
-void dmnsn_rdlock_pixel(const dmnsn_canvas *canvas,
-                        unsigned int x, unsigned int y);
-void dmnsn_wrlock_pixel(dmnsn_canvas *canvas, unsigned int x, unsigned int y);
-void dmnsn_unlock_pixel(const dmnsn_canvas *canvas,
-                        unsigned int x, unsigned int y);
+dmnsn_color *dmnsn_pixel_at(dmnsn_canvas *canvas,
+                            unsigned int x, unsigned int y);
 
 #endif /* DIMENSION_CANVAS_H */
-- 
cgit v1.2.3