diff options
author | Tavian Barnes <tavianator@gmail.com> | 2010-04-07 14:26:15 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2010-04-07 14:34:52 -0400 |
commit | 2b087cb45ae91f90492a935625570d7d42ee3ecb (patch) | |
tree | a464213b08d04c8c91c8879a84e534f895c84378 /libdimension | |
parent | 7d6663eeb68bf9d0a3dff86128827c0c1d85df69 (diff) | |
download | dimension-2b087cb45ae91f90492a935625570d7d42ee3ecb.tar.xz |
New dmnsn_malloc() function, and friends.
I'm tired of checking for malloc failures everywhere, considering it never
happens. So just bail out whenever it does. A lot of stuff is guaranteed
to succeed if it returns now.
Diffstat (limited to 'libdimension')
30 files changed, 411 insertions, 696 deletions
diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am index 2dda68c..9774202 100644 --- a/libdimension/Makefile.am +++ b/libdimension/Makefile.am @@ -34,6 +34,7 @@ nobase_include_HEADERS = dimension.h \ dimension/interior.h \ dimension/light.h \ dimension/lights.h \ + dimension/malloc.h \ dimension/object.h \ dimension/objects.h \ dimension/pigments.h \ @@ -62,6 +63,7 @@ libdimension_la_SOURCES = $(nobase_include_HEADERS) \ inlines.c \ interior.c \ light.c \ + malloc.c \ object.c \ perspective.c \ phong.c \ diff --git a/libdimension/ambient.c b/libdimension/ambient.c index 66fabe0..aa1153a 100644 --- a/libdimension/ambient.c +++ b/libdimension/ambient.c @@ -21,7 +21,6 @@ #include "dimension.h" #include <errno.h> #include <math.h> -#include <stdlib.h> /* For malloc */ /* * Ambient finish @@ -41,18 +40,13 @@ dmnsn_finish * dmnsn_new_ambient_finish(dmnsn_color ambient) { dmnsn_finish *finish = dmnsn_new_finish(); - if (finish) { - dmnsn_color *param = malloc(sizeof(dmnsn_color)); - if (!param) { - dmnsn_delete_finish(finish); - errno = ENOMEM; - return NULL; - } - *param = ambient; - finish->ptr = param; - finish->ambient_fn = &dmnsn_ambient_finish_fn; - finish->free_fn = &free; - } + dmnsn_color *param = dmnsn_malloc(sizeof(dmnsn_color)); + *param = ambient; + + finish->ptr = param; + finish->ambient_fn = &dmnsn_ambient_finish_fn; + finish->free_fn = &free; + return finish; } diff --git a/libdimension/bvst.c b/libdimension/bvst.c index 6e23d6d..958273d 100644 --- a/libdimension/bvst.c +++ b/libdimension/bvst.c @@ -25,22 +25,15 @@ dmnsn_bvst * dmnsn_new_bvst() { - dmnsn_bvst *tree = malloc(sizeof(dmnsn_bvst)); - if (tree) { - tree->root = NULL; - } else { - dmnsn_error(DMNSN_SEVERITY_HIGH, "BVST allocation failed."); - } + dmnsn_bvst *tree = dmnsn_malloc(sizeof(dmnsn_bvst)); + tree->root = NULL; return tree; } static dmnsn_bvst_node * dmnsn_new_bvst_node() { - dmnsn_bvst_node *node = malloc(sizeof(dmnsn_bvst_node)); - if (!node) { - dmnsn_error(DMNSN_SEVERITY_HIGH, "BVST node allocation failed."); - } + dmnsn_bvst_node *node = dmnsn_malloc(sizeof(dmnsn_bvst_node)); return node; } diff --git a/libdimension/camera.c b/libdimension/camera.c index eeb399c..9d30731 100644 --- a/libdimension/camera.c +++ b/libdimension/camera.c @@ -20,18 +20,13 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ /* Allocate a new dummy camera */ dmnsn_camera * dmnsn_new_camera() { - dmnsn_camera *camera = malloc(sizeof(dmnsn_camera)); - if (camera) { - camera->free_fn = NULL; - } else { - errno = ENOMEM; - } + dmnsn_camera *camera = dmnsn_malloc(sizeof(dmnsn_camera)); + camera->free_fn = NULL; return camera; } diff --git a/libdimension/canvas.c b/libdimension/canvas.c index d18d0b7..d6c3c23 100644 --- a/libdimension/canvas.c +++ b/libdimension/canvas.c @@ -21,33 +21,24 @@ #include "dimension.h" #include <pthread.h> #include <errno.h> -#include <stdlib.h> /* For malloc(), free() */ +#include <stdlib.h> /* For free() */ /* Allocate a new canvas, of width x and height y */ dmnsn_canvas * dmnsn_new_canvas(unsigned int x, unsigned int y) { /* Allocate the dmnsn_canvas struct */ - dmnsn_canvas *canvas = malloc(sizeof(dmnsn_canvas)); + dmnsn_canvas *canvas = dmnsn_malloc(sizeof(dmnsn_canvas)); - if (canvas) { - /* Set the width and height */ - canvas->x = x; - canvas->y = y; + /* Set the width and height */ + canvas->x = x; + canvas->y = y; - /* Allocate room for the optimizers */ - canvas->optimizers = dmnsn_new_array(sizeof(dmnsn_canvas_optimizer)); + /* Allocate room for the optimizers */ + canvas->optimizers = dmnsn_new_array(sizeof(dmnsn_canvas_optimizer)); - /* Allocate the pixels */ - canvas->pixels = malloc(sizeof(dmnsn_color)*x*y); - if (!canvas->pixels) { - dmnsn_delete_canvas(canvas); - errno = ENOMEM; - return NULL; - } - } else { - errno = ENOMEM; - } + /* Allocate the pixels */ + canvas->pixels = dmnsn_malloc(sizeof(dmnsn_color)*x*y); return canvas; } diff --git a/libdimension/csg.c b/libdimension/csg.c index 78df625..6342432 100644 --- a/libdimension/csg.c +++ b/libdimension/csg.c @@ -98,48 +98,28 @@ dmnsn_csg_union_inside_fn(const dmnsn_object *csg, dmnsn_vector point) dmnsn_object * dmnsn_new_csg_union(dmnsn_object *A, dmnsn_object *B) { - if (A && B) { - A->trans_inv = dmnsn_matrix_inverse(A->trans); - B->trans_inv = dmnsn_matrix_inverse(B->trans); - - dmnsn_object *csg = dmnsn_new_object(); - if (csg) { - dmnsn_object **params = malloc(2*sizeof(dmnsn_object *)); - if (!params) { - dmnsn_delete_object(csg); - dmnsn_delete_object(B); - dmnsn_delete_object(A); - errno = ENOMEM; - return NULL; - } - - params[0] = A; - params[1] = B; - - csg->ptr = params; - csg->intersection_fn = &dmnsn_csg_union_intersection_fn; - csg->inside_fn = &dmnsn_csg_union_inside_fn; - csg->free_fn = &dmnsn_csg_free_fn; - - dmnsn_bounding_box Abox - = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box); - dmnsn_bounding_box Bbox - = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box); - csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min); - csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max); - - return csg; - } else { - dmnsn_delete_object(B); - dmnsn_delete_object(A); - } - } else if (A) { - dmnsn_delete_object(B); - } else if (B) { - dmnsn_delete_object(A); - } + A->trans_inv = dmnsn_matrix_inverse(A->trans); + B->trans_inv = dmnsn_matrix_inverse(B->trans); + + dmnsn_object *csg = dmnsn_new_object(); + + dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *)); + params[0] = A; + params[1] = B; + + csg->ptr = params; + csg->intersection_fn = &dmnsn_csg_union_intersection_fn; + csg->inside_fn = &dmnsn_csg_union_inside_fn; + csg->free_fn = &dmnsn_csg_free_fn; + + dmnsn_bounding_box Abox + = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box); + dmnsn_bounding_box Bbox + = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box); + csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min); + csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max); - return NULL; + return csg; } /* Intersections */ @@ -237,48 +217,28 @@ dmnsn_csg_intersection_inside_fn(const dmnsn_object *csg, dmnsn_vector point) dmnsn_object * dmnsn_new_csg_intersection(dmnsn_object *A, dmnsn_object *B) { - if (A && B) { - A->trans_inv = dmnsn_matrix_inverse(A->trans); - B->trans_inv = dmnsn_matrix_inverse(B->trans); - - dmnsn_object *csg = dmnsn_new_object(); - if (csg) { - dmnsn_object **params = malloc(2*sizeof(dmnsn_object *)); - if (!params) { - dmnsn_delete_object(csg); - dmnsn_delete_object(B); - dmnsn_delete_object(A); - errno = ENOMEM; - return NULL; - } - - params[0] = A; - params[1] = B; - - csg->ptr = params; - csg->intersection_fn = &dmnsn_csg_intersection_intersection_fn; - csg->inside_fn = &dmnsn_csg_intersection_inside_fn; - csg->free_fn = &dmnsn_csg_free_fn; - - dmnsn_bounding_box Abox - = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box); - dmnsn_bounding_box Bbox - = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box); - csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min); - csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max); - - return csg; - } else { - dmnsn_delete_object(B); - dmnsn_delete_object(A); - } - } else if (A) { - dmnsn_delete_object(B); - } else if (B) { - dmnsn_delete_object(A); - } + A->trans_inv = dmnsn_matrix_inverse(A->trans); + B->trans_inv = dmnsn_matrix_inverse(B->trans); + + dmnsn_object *csg = dmnsn_new_object(); + + dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *)); + params[0] = A; + params[1] = B; + + csg->ptr = params; + csg->intersection_fn = &dmnsn_csg_intersection_intersection_fn; + csg->inside_fn = &dmnsn_csg_intersection_inside_fn; + csg->free_fn = &dmnsn_csg_free_fn; + + dmnsn_bounding_box Abox + = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box); + dmnsn_bounding_box Bbox + = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box); + csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min); + csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max); - return NULL; + return csg; } /* Differences */ @@ -376,48 +336,28 @@ dmnsn_csg_difference_inside_fn(const dmnsn_object *csg, dmnsn_vector point) dmnsn_object * dmnsn_new_csg_difference(dmnsn_object *A, dmnsn_object *B) { - if (A && B) { - A->trans_inv = dmnsn_matrix_inverse(A->trans); - B->trans_inv = dmnsn_matrix_inverse(B->trans); - - dmnsn_object *csg = dmnsn_new_object(); - if (csg) { - dmnsn_object **params = malloc(2*sizeof(dmnsn_object *)); - if (!params) { - dmnsn_delete_object(csg); - dmnsn_delete_object(B); - dmnsn_delete_object(A); - errno = ENOMEM; - return NULL; - } - - params[0] = A; - params[1] = B; - - csg->ptr = params; - csg->intersection_fn = &dmnsn_csg_difference_intersection_fn; - csg->inside_fn = &dmnsn_csg_difference_inside_fn; - csg->free_fn = &dmnsn_csg_free_fn; - - dmnsn_bounding_box Abox - = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box); - dmnsn_bounding_box Bbox - = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box); - csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min); - csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max); - - return csg; - } else { - dmnsn_delete_object(B); - dmnsn_delete_object(A); - } - } else if (A) { - dmnsn_delete_object(B); - } else if (B) { - dmnsn_delete_object(A); - } + A->trans_inv = dmnsn_matrix_inverse(A->trans); + B->trans_inv = dmnsn_matrix_inverse(B->trans); + + dmnsn_object *csg = dmnsn_new_object(); + + dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *)); + params[0] = A; + params[1] = B; + + csg->ptr = params; + csg->intersection_fn = &dmnsn_csg_difference_intersection_fn; + csg->inside_fn = &dmnsn_csg_difference_inside_fn; + csg->free_fn = &dmnsn_csg_free_fn; + + dmnsn_bounding_box Abox + = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box); + dmnsn_bounding_box Bbox + = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box); + csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min); + csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max); - return NULL; + return csg; } /* Merges */ @@ -515,46 +455,26 @@ dmnsn_csg_merge_inside_fn(const dmnsn_object *csg, dmnsn_vector point) dmnsn_object * dmnsn_new_csg_merge(dmnsn_object *A, dmnsn_object *B) { - if (A && B) { - A->trans_inv = dmnsn_matrix_inverse(A->trans); - B->trans_inv = dmnsn_matrix_inverse(B->trans); - - dmnsn_object *csg = dmnsn_new_object(); - if (csg) { - dmnsn_object **params = malloc(2*sizeof(dmnsn_object *)); - if (!params) { - dmnsn_delete_object(csg); - dmnsn_delete_object(B); - dmnsn_delete_object(A); - errno = ENOMEM; - return NULL; - } - - params[0] = A; - params[1] = B; - - csg->ptr = params; - csg->intersection_fn = &dmnsn_csg_merge_intersection_fn; - csg->inside_fn = &dmnsn_csg_merge_inside_fn; - csg->free_fn = &dmnsn_csg_free_fn; - - dmnsn_bounding_box Abox - = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box); - dmnsn_bounding_box Bbox - = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box); - csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min); - csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max); - - return csg; - } else { - dmnsn_delete_object(B); - dmnsn_delete_object(A); - } - } else if (A) { - dmnsn_delete_object(B); - } else if (B) { - dmnsn_delete_object(A); - } + A->trans_inv = dmnsn_matrix_inverse(A->trans); + B->trans_inv = dmnsn_matrix_inverse(B->trans); + + dmnsn_object *csg = dmnsn_new_object(); + + dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *)); + params[0] = A; + params[1] = B; + + csg->ptr = params; + csg->intersection_fn = &dmnsn_csg_merge_intersection_fn; + csg->inside_fn = &dmnsn_csg_merge_inside_fn; + csg->free_fn = &dmnsn_csg_free_fn; + + dmnsn_bounding_box Abox + = dmnsn_matrix_bounding_box_mul(A->trans, A->bounding_box); + dmnsn_bounding_box Bbox + = dmnsn_matrix_bounding_box_mul(B->trans, B->bounding_box); + csg->bounding_box.min = dmnsn_vector_min(Abox.min, Bbox.min); + csg->bounding_box.max = dmnsn_vector_max(Abox.max, Bbox.max); - return NULL; + return csg; } diff --git a/libdimension/cube.c b/libdimension/cube.c index a6f656d..033d2fb 100644 --- a/libdimension/cube.c +++ b/libdimension/cube.c @@ -19,8 +19,7 @@ *************************************************************************/ #include "dimension.h" -#include <stdlib.h> /* For malloc */ -#include <math.h> /* For sqrt */ +#include <math.h> /* For sqrt */ /* * Cube @@ -37,12 +36,10 @@ dmnsn_object * dmnsn_new_cube() { dmnsn_object *cube = dmnsn_new_object(); - if (cube) { - cube->intersection_fn = &dmnsn_cube_intersection_fn; - cube->inside_fn = &dmnsn_cube_inside_fn; - cube->bounding_box.min = dmnsn_new_vector(-1.0, -1.0, -1.0); - cube->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 1.0); - } + cube->intersection_fn = &dmnsn_cube_intersection_fn; + cube->inside_fn = &dmnsn_cube_inside_fn; + cube->bounding_box.min = dmnsn_new_vector(-1.0, -1.0, -1.0); + cube->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 1.0); return cube; } diff --git a/libdimension/diffuse.c b/libdimension/diffuse.c index d6ecf37..dc41944 100644 --- a/libdimension/diffuse.c +++ b/libdimension/diffuse.c @@ -20,7 +20,6 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ #include <math.h> /* @@ -45,19 +44,13 @@ dmnsn_finish * dmnsn_new_diffuse_finish(double diffuse) { dmnsn_finish *finish = dmnsn_new_finish(); - if (finish) { - double *param = malloc(sizeof(double)); - if (!param) { - dmnsn_delete_finish(finish); - errno = ENOMEM; - return NULL; - } - *param = diffuse; + double *param = dmnsn_malloc(sizeof(double)); + *param = diffuse; + + finish->ptr = param; + finish->diffuse_fn = &dmnsn_diffuse_finish_fn; + finish->free_fn = &free; - finish->ptr = param; - finish->diffuse_fn = &dmnsn_diffuse_finish_fn; - finish->free_fn = &free; - } return finish; } diff --git a/libdimension/dimension.h b/libdimension/dimension.h index e693841..5aca9b3 100644 --- a/libdimension/dimension.h +++ b/libdimension/dimension.h @@ -61,6 +61,7 @@ typedef void dmnsn_free_fn(void *ptr); /* Include all the libdimension headers */ #include <dimension/error.h> +#include <dimension/malloc.h> #include <dimension/array.h> #include <dimension/progress.h> #include <dimension/geometry.h> diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h index c1e28cd..a301de5 100644 --- a/libdimension/dimension/array.h +++ b/libdimension/dimension/array.h @@ -28,7 +28,7 @@ #define DIMENSION_ARRAY_H #include <pthread.h> /* For pthread_rwlock_t */ -#include <stdlib.h> /* For size_t, malloc */ +#include <stdlib.h> /* For size_t */ #include <string.h> /* For memcpy */ typedef struct { @@ -46,26 +46,17 @@ dmnsn_delete_array(dmnsn_array *array) } } -/* Array allocation never returns NULL - if dmnsn_new_array returns, it - succeeded */ +/* Array allocation */ DMNSN_INLINE dmnsn_array * dmnsn_new_array(size_t obj_size) { - dmnsn_array *array = (dmnsn_array *)malloc(sizeof(dmnsn_array)); - if (array) { - array->obj_size = obj_size; - array->length = 0; - array->capacity = 4; /* Start with capacity of 4 */ - - /* Allocate the memory */ - array->ptr = malloc(array->capacity*array->obj_size); - if (!array->ptr) { - dmnsn_delete_array(array); - dmnsn_error(DMNSN_SEVERITY_HIGH, "Array allocation failed."); - } - } else { - dmnsn_error(DMNSN_SEVERITY_HIGH, "Array allocation failed."); - } + dmnsn_array *array = (dmnsn_array *)dmnsn_malloc(sizeof(dmnsn_array)); + array->obj_size = obj_size; + array->length = 0; + array->capacity = 4; /* Start with capacity of 4 */ + + /* Allocate the memory */ + array->ptr = dmnsn_malloc(array->capacity*array->obj_size); return array; } @@ -84,10 +75,7 @@ dmnsn_array_resize(dmnsn_array *array, size_t length) if (length > array->capacity) { /* Resize if we don't have enough capacity */ array->capacity = length*2; /* We are greedy */ - array->ptr = realloc(array->ptr, array->obj_size*array->capacity); - if (!array->ptr) { - dmnsn_error(DMNSN_SEVERITY_HIGH, "Resizing array failed."); - } + array->ptr = dmnsn_realloc(array->ptr, array->obj_size*array->capacity); } array->length = length; diff --git a/libdimension/dimension/malloc.h b/libdimension/dimension/malloc.h new file mode 100644 index 0000000..8ca4f9d --- /dev/null +++ b/libdimension/dimension/malloc.h @@ -0,0 +1,31 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.com> * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * <http://www.gnu.org/licenses/>. * + *************************************************************************/ + +/* + * Seriously, how often does malloc fail? And how often can you do something + * better than bail out when it does? dmnsn_malloc() is like malloc in every + * way except it calls dmnsn_error() on failure. + */ + +#include <stdlib.h> /* For size_t */ + +void *dmnsn_malloc(size_t size); +void *dmnsn_realloc(void *ptr, size_t size); +char *dmnsn_strdup(const char *s); diff --git a/libdimension/dimension/raytrace.h b/libdimension/dimension/raytrace.h index 1c7d875..914f944 100644 --- a/libdimension/dimension/raytrace.h +++ b/libdimension/dimension/raytrace.h @@ -26,7 +26,7 @@ #define DIMENSION_RAYTRACE_H /* Render a scene by raytracing */ -int dmnsn_raytrace_scene(dmnsn_scene *scene); +void dmnsn_raytrace_scene(dmnsn_scene *scene); dmnsn_progress *dmnsn_raytrace_scene_async(dmnsn_scene *scene); #endif /* DIMENSION_RAYTRACE_H */ diff --git a/libdimension/error.c b/libdimension/error.c index 118dd54..222f5eb 100644 --- a/libdimension/error.c +++ b/libdimension/error.c @@ -153,8 +153,9 @@ dmnsn_default_fatal_error_fn() if (pid == tid) { exit(EXIT_FAILURE); } else { - int *ret = malloc(sizeof(int)); - *ret = 1; + int *ret = malloc(sizeof(int)); /* Don't use dmnsn_malloc */ + if (ret) + *ret = 1; pthread_exit(ret); } #else diff --git a/libdimension/finish_combination.c b/libdimension/finish_combination.c index 472dc23..c281285 100644 --- a/libdimension/finish_combination.c +++ b/libdimension/finish_combination.c @@ -20,7 +20,6 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ #include <math.h> /* @@ -119,47 +118,27 @@ dmnsn_finish_combination_free_fn(void *ptr) dmnsn_finish * dmnsn_new_finish_combination(dmnsn_finish *f1, dmnsn_finish *f2) { - if (f1 && f2) { - dmnsn_finish *finish = dmnsn_new_finish(); - if (finish) { - dmnsn_finish **params = malloc(2*sizeof(dmnsn_finish *)); - if (!params) { - dmnsn_delete_finish(finish); - dmnsn_delete_finish(f2); - dmnsn_delete_finish(f1); - errno = ENOMEM; - return NULL; - } - - params[0] = f1; - params[1] = f2; - - finish->ptr = params; - - if (f1->diffuse_fn || f2->diffuse_fn) - finish->diffuse_fn = &dmnsn_finish_combination_diffuse_fn; - - if (f1->specular_fn || f2->specular_fn) - finish->specular_fn = &dmnsn_finish_combination_specular_fn; - - if (f1->ambient_fn || f2->ambient_fn) - finish->ambient_fn = &dmnsn_finish_combination_ambient_fn; - - if (f1->reflection_fn || f2->reflection_fn) - finish->reflection_fn = &dmnsn_finish_combination_reflection_fn; - - finish->free_fn = &dmnsn_finish_combination_free_fn; - - return finish; - } else { - dmnsn_delete_finish(f2); - dmnsn_delete_finish(f1); - } - } else if (f1) { - dmnsn_delete_finish(f1); - } else if (f2) { - dmnsn_delete_finish(f2); - } + dmnsn_finish *finish = dmnsn_new_finish(); + + dmnsn_finish **params = dmnsn_malloc(2*sizeof(dmnsn_finish *)); + params[0] = f1; + params[1] = f2; + + finish->ptr = params; + + if (f1->diffuse_fn || f2->diffuse_fn) + finish->diffuse_fn = &dmnsn_finish_combination_diffuse_fn; + + if (f1->specular_fn || f2->specular_fn) + finish->specular_fn = &dmnsn_finish_combination_specular_fn; + + if (f1->ambient_fn || f2->ambient_fn) + finish->ambient_fn = &dmnsn_finish_combination_ambient_fn; + + if (f1->reflection_fn || f2->reflection_fn) + finish->reflection_fn = &dmnsn_finish_combination_reflection_fn; + + finish->free_fn = &dmnsn_finish_combination_free_fn; - return NULL; + return finish; } diff --git a/libdimension/gl.c b/libdimension/gl.c index 0136ac3..86f41e4 100644 --- a/libdimension/gl.c +++ b/libdimension/gl.c @@ -48,11 +48,7 @@ dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas) optimizer.free_fn = &free; /* Allocate a buffer to hold RGB values */ - optimizer.ptr = malloc(4*canvas->x*canvas->y*sizeof(GLushort)); - if (!optimizer.ptr) { - errno = ENOTSUP; - return -1; - } + optimizer.ptr = dmnsn_malloc(4*canvas->x*canvas->y*sizeof(GLushort)); /* Set a new optimizer */ dmnsn_optimize_canvas(canvas, optimizer); @@ -83,11 +79,7 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas) } /* We couldn't, so transform the canvas to RGB now */ - pixels = malloc(4*width*height*sizeof(GLushort)); - if (!pixels) { - errno = ENOMEM; - return -1; - } + pixels = dmnsn_malloc(4*width*height*sizeof(GLushort)); for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { @@ -146,16 +138,7 @@ dmnsn_gl_read_canvas(unsigned int x0, unsigned int y0, unsigned int x, y; canvas = dmnsn_new_canvas(width, height); - if (!canvas) { - return NULL; - } - - pixels = malloc(4*width*height*sizeof(GLushort)); - if (!pixels) { - dmnsn_delete_canvas(canvas); - errno = ENOMEM; - return NULL; - } + pixels = dmnsn_malloc(4*width*height*sizeof(GLushort)); glReadPixels(x0, y0, width, height, GL_RGBA, GL_UNSIGNED_SHORT, pixels); diff --git a/libdimension/interior.c b/libdimension/interior.c index 546a420..452d879 100644 --- a/libdimension/interior.c +++ b/libdimension/interior.c @@ -20,19 +20,14 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ /* Allocate an interior */ dmnsn_interior * dmnsn_new_interior() { - dmnsn_interior *interior = malloc(sizeof(dmnsn_interior)); - if (interior) { - interior->ior = 1.0; - interior->free_fn = NULL; - } else { - errno = ENOMEM; - } + dmnsn_interior *interior = dmnsn_malloc(sizeof(dmnsn_interior)); + interior->ior = 1.0; + interior->free_fn = NULL; return interior; } diff --git a/libdimension/light.c b/libdimension/light.c index cc2c961..8be90e0 100644 --- a/libdimension/light.c +++ b/libdimension/light.c @@ -20,20 +20,15 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ /* Allocate a new dummy light */ dmnsn_light * dmnsn_new_light() { - dmnsn_light *light = malloc(sizeof(dmnsn_light)); - if (light) { - light->light_fn = NULL; - light->free_fn = NULL; - light->ptr = NULL; - } else { - errno = ENOMEM; - } + dmnsn_light *light = dmnsn_malloc(sizeof(dmnsn_light)); + light->light_fn = NULL; + light->free_fn = NULL; + light->ptr = NULL; return light; } diff --git a/libdimension/malloc.c b/libdimension/malloc.c new file mode 100644 index 0000000..f1f234e --- /dev/null +++ b/libdimension/malloc.c @@ -0,0 +1,50 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.com> * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * <http://www.gnu.org/licenses/>. * + *************************************************************************/ + +#include "dimension.h" +#include <string.h> + +void * +dmnsn_malloc(size_t size) +{ + void *ptr = malloc(size); + if (!ptr) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Memory allocation failed."); + } + return ptr; +} + +void * +dmnsn_realloc(void *ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (!ptr) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Memory allocation failed."); + } + return ptr; +} + +char * +dmnsn_strdup(const char *s) +{ + char *copy = dmnsn_malloc(strlen(s) + 1); + strcpy(copy, s); + return copy; +} diff --git a/libdimension/object.c b/libdimension/object.c index 9f17971..51db42f 100644 --- a/libdimension/object.c +++ b/libdimension/object.c @@ -20,16 +20,12 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ -/* Allocate an intersection - cannot fail */ +/* Allocate an intersection */ dmnsn_intersection * dmnsn_new_intersection() { - dmnsn_intersection *intersection = malloc(sizeof(dmnsn_intersection)); - if (!intersection) { - dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate an intersection."); - } + dmnsn_intersection *intersection = dmnsn_malloc(sizeof(dmnsn_intersection)); return intersection; } @@ -44,15 +40,11 @@ dmnsn_delete_intersection(dmnsn_intersection *intersection) dmnsn_object * dmnsn_new_object() { - dmnsn_object *object = malloc(sizeof(dmnsn_object)); - if (object) { - object->texture = NULL; - object->interior = NULL; - object->trans = dmnsn_identity_matrix(); - object->free_fn = NULL; - } else { - errno = ENOMEM; - } + dmnsn_object *object = dmnsn_malloc(sizeof(dmnsn_object)); + object->texture = NULL; + object->interior = NULL; + object->trans = dmnsn_identity_matrix(); + object->free_fn = NULL; return object; } diff --git a/libdimension/perspective.c b/libdimension/perspective.c index df679ae..678c87b 100644 --- a/libdimension/perspective.c +++ b/libdimension/perspective.c @@ -35,22 +35,15 @@ static dmnsn_line dmnsn_perspective_camera_ray_fn(const dmnsn_camera *camera, dmnsn_camera * dmnsn_new_perspective_camera() { - dmnsn_matrix *ptr; dmnsn_camera *camera = dmnsn_new_camera(); - if (camera) { - /* Allocate room for the transformation matrix */ - ptr = malloc(sizeof(dmnsn_matrix)); - if (!ptr) { - dmnsn_delete_camera(camera); - errno = ENOMEM; - return NULL; - } - *ptr = dmnsn_identity_matrix(); - camera->ray_fn = &dmnsn_perspective_camera_ray_fn; - camera->free_fn = &free; - camera->ptr = ptr; - } + dmnsn_matrix *ptr = dmnsn_malloc(sizeof(dmnsn_matrix)); + *ptr = dmnsn_identity_matrix(); + + camera->ray_fn = &dmnsn_perspective_camera_ray_fn; + camera->free_fn = &free; + camera->ptr = ptr; + return camera; } diff --git a/libdimension/phong.c b/libdimension/phong.c index 8188488..ae7b2ce 100644 --- a/libdimension/phong.c +++ b/libdimension/phong.c @@ -20,7 +20,6 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ #include <math.h> /* @@ -55,20 +54,14 @@ dmnsn_finish * dmnsn_new_phong_finish(double specular, double exp) { dmnsn_finish *finish = dmnsn_new_finish(); - if (finish) { - double *params = malloc(2*sizeof(double)); - if (!params) { - dmnsn_delete_finish(finish); - errno = ENOMEM; - return NULL; - } - params[0] = specular; - params[1] = exp; + double *params = dmnsn_malloc(2*sizeof(double)); + params[0] = specular; + params[1] = exp; + + finish->ptr = params; + finish->specular_fn = &dmnsn_phong_specular_fn; + finish->free_fn = &free; - finish->ptr = params; - finish->specular_fn = &dmnsn_phong_specular_fn; - finish->free_fn = &free; - } return finish; } diff --git a/libdimension/png.c b/libdimension/png.c index 4f622dc..76bace9 100644 --- a/libdimension/png.c +++ b/libdimension/png.c @@ -50,11 +50,7 @@ dmnsn_png_optimize_canvas(dmnsn_canvas *canvas) optimizer.optimizer_fn = &dmnsn_png_optimizer_fn; optimizer.free_fn = &free; - optimizer.ptr = malloc(4*canvas->x*canvas->y*sizeof(uint16_t)); - if (!optimizer.ptr) { - errno = ENOMEM; - return -1; - } + optimizer.ptr = dmnsn_malloc(4*canvas->x*canvas->y*sizeof(uint16_t)); dmnsn_optimize_canvas(canvas, optimizer); return 0; @@ -140,28 +136,20 @@ dmnsn_progress * dmnsn_png_write_canvas_async(const dmnsn_canvas *canvas, FILE *file) { dmnsn_progress *progress = dmnsn_new_progress(); - dmnsn_png_write_payload *payload; - if (progress) { - payload = malloc(sizeof(dmnsn_png_write_payload)); - if (!payload) { - dmnsn_delete_progress(progress); - errno = ENOMEM; - return NULL; - } + dmnsn_png_write_payload *payload + = dmnsn_malloc(sizeof(dmnsn_png_write_payload)); + payload->progress = progress; + payload->canvas = canvas; + payload->file = file; - payload->progress = progress; - payload->canvas = canvas; - payload->file = file; - - /* Create the worker thread */ - if (pthread_create(&progress->thread, NULL, &dmnsn_png_write_canvas_thread, - payload) != 0) - { - free(payload); - dmnsn_delete_progress(progress); - return NULL; - } + /* Create the worker thread */ + if (pthread_create(&progress->thread, NULL, &dmnsn_png_write_canvas_thread, + payload) != 0) + { + free(payload); + dmnsn_delete_progress(progress); + return NULL; } return progress; @@ -182,28 +170,18 @@ dmnsn_progress * dmnsn_png_read_canvas_async(dmnsn_canvas **canvas, FILE *file) { dmnsn_progress *progress = dmnsn_new_progress(); - dmnsn_png_read_payload *payload; + dmnsn_png_read_payload *payload + = dmnsn_malloc(sizeof(dmnsn_png_write_payload)); - if (progress) { - payload = malloc(sizeof(dmnsn_png_write_payload)); - if (!payload) { - dmnsn_delete_progress(progress); - errno = ENOMEM; - return NULL; - } + payload->progress = progress; + payload->canvas = canvas; + payload->file = file; - payload->progress = progress; - payload->canvas = canvas; - payload->file = file; - - /* Create the worker thread */ - if (pthread_create(&progress->thread, NULL, &dmnsn_png_read_canvas_thread, - payload) != 0) - { - free(payload); - dmnsn_delete_progress(progress); - return NULL; - } + /* Create the worker thread */ + if (pthread_create(&progress->thread, NULL, &dmnsn_png_read_canvas_thread, + payload) != 0) + { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't start worker thread."); } return progress; @@ -221,11 +199,9 @@ static void * dmnsn_png_write_canvas_thread(void *ptr) { dmnsn_png_write_payload *payload = ptr; - int *retval = malloc(sizeof(int)); - if (retval) { - *retval = dmnsn_png_write_canvas_impl(payload->progress, - payload->canvas, payload->file); - } + int *retval = dmnsn_malloc(sizeof(int)); + *retval = dmnsn_png_write_canvas_impl(payload->progress, + payload->canvas, payload->file); dmnsn_done_progress(payload->progress); free(payload); return retval; @@ -235,12 +211,12 @@ static void * dmnsn_png_read_canvas_thread(void *ptr) { dmnsn_png_read_payload *payload = ptr; - int *retval = malloc(sizeof(int)); - if (retval) { - *payload->canvas = dmnsn_png_read_canvas_impl(payload->progress, - payload->file); - *retval = *payload->canvas ? 0 : -1; /* Fail if it returned NULL */ - } + *payload->canvas = dmnsn_png_read_canvas_impl(payload->progress, + payload->file); + + int *retval = dmnsn_malloc(sizeof(int)); + *retval = *payload->canvas ? 0 : -1; /* Fail if it returned NULL */ + dmnsn_done_progress(payload->progress); free(payload); return retval; @@ -331,12 +307,7 @@ dmnsn_png_write_canvas_impl(dmnsn_progress *progress, } /* Allocate the temporary row of RGBA values */ - row = malloc(4*sizeof(uint16_t)*width); - if (!row) { - png_destroy_write_struct(&png_ptr, &info_ptr); - errno = ENOMEM; - return -1; - } + row = dmnsn_malloc(4*sizeof(uint16_t)*width); /* Write the pixels */ for (y = 0; y < height; ++y) { @@ -524,22 +495,10 @@ dmnsn_png_read_canvas_impl(dmnsn_progress *progress, FILE *file) rowbytes = png_get_rowbytes(png_ptr, info_ptr); /* Allocate the temporary image buffer */ - image = malloc(rowbytes*height); - if (!image) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - errno = ENOMEM; - return NULL; - } + image = dmnsn_malloc(rowbytes*height); /* Allocate and set an array of pointers to rows in image */ - - row_pointers = malloc(sizeof(png_bytep)*height); - if (!row_pointers) { - free(image); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - errno = ENOMEM; - return NULL; - } + row_pointers = dmnsn_malloc(sizeof(png_bytep)*height); for (y = 0; y < height; ++y) { row_pointers[y] = image + y*rowbytes; @@ -551,13 +510,6 @@ dmnsn_png_read_canvas_impl(dmnsn_progress *progress, FILE *file) /* Allocate the canvas */ canvas = dmnsn_new_canvas(width, height); - if (!canvas) { - free(row_pointers); - free(image); - png_read_end(png_ptr, NULL); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return NULL; - } /* Now we convert the image to our canvas format. This depends on the image bit depth (which has been scaled up to at least 8 or 16), and the presence diff --git a/libdimension/point_light.c b/libdimension/point_light.c index 1ca3c96..02ab2ea 100644 --- a/libdimension/point_light.c +++ b/libdimension/point_light.c @@ -35,20 +35,14 @@ dmnsn_light * dmnsn_new_point_light(dmnsn_vector x0, dmnsn_color color) { dmnsn_light *light = dmnsn_new_light(); - if (light) { - /* Allocate room for the transformation matrix */ - dmnsn_color *ptr = malloc(sizeof(dmnsn_color)); - if (!ptr) { - dmnsn_delete_light(light); - errno = ENOMEM; - return NULL; - } - *ptr = color; - light->x0 = x0; - light->light_fn = &dmnsn_point_light_fn; - light->free_fn = &free; - light->ptr = ptr; - } + dmnsn_color *ptr = dmnsn_malloc(sizeof(dmnsn_color)); + *ptr = color; + + light->x0 = x0; + light->light_fn = &dmnsn_point_light_fn; + light->free_fn = &free; + light->ptr = ptr; + return light; } diff --git a/libdimension/progress.c b/libdimension/progress.c index 998af8e..bc8830b 100644 --- a/libdimension/progress.c +++ b/libdimension/progress.c @@ -21,7 +21,6 @@ #include "dimension.h" #include <pthread.h> #include <errno.h> -#include <stdlib.h> /* For malloc */ /* For thread synchronization */ static void dmnsn_progress_rdlock(const dmnsn_progress *progress); @@ -32,70 +31,44 @@ static void dmnsn_progress_unlock(const dmnsn_progress *progress); dmnsn_progress * dmnsn_new_progress() { - dmnsn_progress_element element = { .progress = 0, .total = 1 }; - dmnsn_progress *progress = malloc(sizeof(dmnsn_progress)); - if (progress) { - progress->elements = dmnsn_new_array(sizeof(dmnsn_progress_element)); - dmnsn_array_push(progress->elements, &element); + dmnsn_progress *progress = dmnsn_malloc(sizeof(dmnsn_progress)); + progress->elements = dmnsn_new_array(sizeof(dmnsn_progress_element)); - /* Initialize the rwlock, condition variable, and mutex */ + dmnsn_progress_element element = { .progress = 0, .total = 1 }; + dmnsn_array_push(progress->elements, &element); - progress->rwlock = NULL; - progress->mutex = NULL; - progress->cond = NULL; + /* Initialize the rwlock, condition variable, and mutex */ - progress->rwlock = malloc(sizeof(pthread_rwlock_t)); - if (!progress->rwlock) { - dmnsn_delete_progress(progress); - errno = ENOMEM; - return NULL; - } - if (pthread_rwlock_init(progress->rwlock, NULL) != 0) { - dmnsn_delete_progress(progress); - return NULL; - } + progress->rwlock = dmnsn_malloc(sizeof(pthread_rwlock_t)); + if (pthread_rwlock_init(progress->rwlock, NULL) != 0) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't initialize read-write lock."); + } - progress->cond = malloc(sizeof(pthread_cond_t)); - if (!progress->cond) { - dmnsn_delete_progress(progress); - errno = ENOMEM; - return NULL; - } - if (pthread_cond_init(progress->cond, NULL) != 0) { - dmnsn_delete_progress(progress); - return NULL; - } + progress->cond = dmnsn_malloc(sizeof(pthread_cond_t)); + if (pthread_cond_init(progress->cond, NULL) != 0) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't initialize condition variable."); + } - progress->mutex = malloc(sizeof(pthread_mutex_t)); - if (!progress->mutex) { - dmnsn_delete_progress(progress); - errno = ENOMEM; - return NULL; - } - if (pthread_mutex_init(progress->mutex, NULL) != 0) { - dmnsn_delete_progress(progress); - return NULL; - } - } else { - errno = ENOMEM; + progress->mutex = dmnsn_malloc(sizeof(pthread_mutex_t)); + if (pthread_mutex_init(progress->mutex, NULL) != 0) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't initialize mutex."); } return progress; } -/* Delete a dmnsn_progress*, which has not yet been associated with a thread; - mostly for failed returns from *_async() functions. */ +/* Delete a dmnsn_progress*, which has not yet been associated with a thread */ void dmnsn_delete_progress(dmnsn_progress *progress) { if (progress) { - if (progress->rwlock && pthread_rwlock_destroy(progress->rwlock) != 0) { + if (pthread_rwlock_destroy(progress->rwlock) != 0) { dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking rwlock."); } - if (progress->mutex && pthread_mutex_destroy(progress->mutex) != 0) { + if (pthread_mutex_destroy(progress->mutex) != 0) { dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking mutex."); } - if (progress->cond && pthread_cond_destroy(progress->cond) != 0) { + if (pthread_cond_destroy(progress->cond) != 0) { dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking condition variable."); } diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index 840f6f2..812b6a6 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -40,68 +40,55 @@ typedef struct { static void *dmnsn_raytrace_scene_thread(void *ptr); /* Raytrace a scene */ -int +void dmnsn_raytrace_scene(dmnsn_scene *scene) { dmnsn_progress *progress = dmnsn_raytrace_scene_async(scene); - return dmnsn_finish_progress(progress); + dmnsn_finish_progress(progress); } /* Raytrace a scene in the background */ dmnsn_progress * dmnsn_raytrace_scene_async(dmnsn_scene *scene) { - unsigned int i; - dmnsn_object *object; - dmnsn_raytrace_payload *payload; dmnsn_progress *progress = dmnsn_new_progress(); - if (progress) { - payload = malloc(sizeof(dmnsn_raytrace_payload)); - if (!payload) { - dmnsn_delete_progress(progress); - errno = ENOMEM; - return NULL; - } - - payload->progress = progress; - payload->scene = scene; - payload->bvst = dmnsn_new_bvst(); + dmnsn_raytrace_payload *payload + = dmnsn_malloc(sizeof(dmnsn_raytrace_payload)); + payload->progress = progress; + payload->scene = scene; + payload->bvst = dmnsn_new_bvst(); - for (i = 0; i < dmnsn_array_size(payload->scene->objects); ++i) { - dmnsn_array_get(payload->scene->objects, i, &object); - dmnsn_bvst_insert(payload->bvst, object); - } + unsigned int i; + for (i = 0; i < dmnsn_array_size(payload->scene->objects); ++i) { + dmnsn_object *object; + dmnsn_array_get(payload->scene->objects, i, &object); + dmnsn_bvst_insert(payload->bvst, object); + } - if (pthread_create(&progress->thread, NULL, &dmnsn_raytrace_scene_thread, - payload) != 0) - { - dmnsn_delete_bvst(payload->bvst); - free(payload); - dmnsn_delete_progress(progress); - return NULL; - } + if (pthread_create(&progress->thread, NULL, &dmnsn_raytrace_scene_thread, + payload) != 0) + { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't start worker thread."); } return progress; } /* Start the multi-threaded implementation */ -static int dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload); +static void dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload); /* Thread callback */ static void * dmnsn_raytrace_scene_thread(void *ptr) { dmnsn_raytrace_payload *payload = ptr; - int *retval = malloc(sizeof(int)); - if (retval) { - *retval = dmnsn_raytrace_scene_multithread(payload); - } else { - errno = ENOMEM; - } + dmnsn_raytrace_scene_multithread(payload); dmnsn_done_progress(payload->progress); free(payload); + + int *retval = dmnsn_malloc(sizeof(int)); + *retval = 0; return retval; } @@ -109,12 +96,9 @@ dmnsn_raytrace_scene_thread(void *ptr) static void *dmnsn_raytrace_scene_multithread_thread(void *ptr); /* Set up the multi-threaded engine */ -static int +static void dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload) { - int i, j; - void *ptr; - int retval = 0; dmnsn_raytrace_payload *payloads; pthread_t *threads; @@ -123,24 +107,15 @@ dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload) if (nthreads < 1) nthreads = 1; - payloads = malloc(nthreads*sizeof(dmnsn_raytrace_payload)); - if (!payloads) { - errno = ENOMEM; - return -1; - } - - threads = malloc(nthreads*sizeof(pthread_t)); - if (!threads) { - free(payloads); - errno = ENOMEM; - return -1; - } + payloads = dmnsn_malloc(nthreads*sizeof(dmnsn_raytrace_payload)); + threads = dmnsn_malloc(nthreads*sizeof(pthread_t)); /* Set up the progress object */ dmnsn_new_progress_element(payload->progress, payload->scene->canvas->y); /* Create the payloads */ + unsigned int i; for (i = 0; i < nthreads; ++i) { payloads[i] = *payload; payloads[i].index = i; @@ -156,62 +131,38 @@ dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload) &dmnsn_raytrace_scene_multithread_thread, &payloads[i]) != 0) { - for (j = 0; j < i; ++j) { - if (pthread_join(threads[j], &ptr)) { - dmnsn_error(DMNSN_SEVERITY_MEDIUM, - "Couldn't join worker thread in failed raytrace engine" - " initialization."); - } else { - /* Only free on a successful join - otherwise we might free a pointer - out from under a running thread */ - dmnsn_delete_bvst(payloads[j].bvst); - free(ptr); - } - } - - free(payloads); - return -1; + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Couldn't start worker thread in raytrace engine."); } } for (i = 0; i < nthreads; ++i) { - if (pthread_join(threads[i], &ptr)) { + if (pthread_join(threads[i], NULL)) { dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't join worker thread in raytrace engine."); } else { - if (retval == 0) { - retval = *(int *)ptr; - } dmnsn_delete_bvst(payloads[i].bvst); - free(ptr); } } free(threads); free(payloads); - return retval; } /* Actual raytracing implementation */ -static int dmnsn_raytrace_scene_impl(dmnsn_progress *progress, - dmnsn_scene *scene, - dmnsn_bvst *bvst, - unsigned int index, unsigned int threads); +static void dmnsn_raytrace_scene_impl(dmnsn_progress *progress, + dmnsn_scene *scene, + dmnsn_bvst *bvst, + unsigned int index, unsigned int threads); /* Multi-threading thread callback */ static void * dmnsn_raytrace_scene_multithread_thread(void *ptr) { dmnsn_raytrace_payload *payload = ptr; - int *retval = malloc(sizeof(int)); - if (retval) { - *retval = dmnsn_raytrace_scene_impl(payload->progress, payload->scene, - payload->bvst, - payload->index, payload->threads); - } else { - errno = ENOMEM; - } - return retval; + dmnsn_raytrace_scene_impl(payload->progress, payload->scene, + payload->bvst, payload->index, payload->threads); + return NULL; } /* @@ -242,7 +193,7 @@ static dmnsn_color dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray); /* Actually raytrace a scene */ -static int +static void dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene, dmnsn_bvst *bvst, unsigned int index, unsigned int threads) @@ -283,8 +234,6 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene, dmnsn_increment_progress(progress); } - - return 0; } #define ITEXTURE(state) (state->intersection->texture) diff --git a/libdimension/reflective.c b/libdimension/reflective.c index 2e90b8f..24b6efb 100644 --- a/libdimension/reflective.c +++ b/libdimension/reflective.c @@ -20,7 +20,6 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ #include <math.h> /* @@ -50,21 +49,16 @@ dmnsn_finish * dmnsn_new_reflective_finish(dmnsn_color min, dmnsn_color max, double falloff) { dmnsn_finish *finish = dmnsn_new_finish(); - if (finish) { - dmnsn_reflection_params *params = malloc(sizeof(dmnsn_reflection_params)); - if (!params) { - dmnsn_delete_finish(finish); - errno = ENOMEM; - return NULL; - } - params->min = min; - params->max = max; - params->falloff = falloff; + dmnsn_reflection_params *params + = dmnsn_malloc(sizeof(dmnsn_reflection_params)); + params->min = min; + params->max = max; + params->falloff = falloff; + + finish->ptr = params; + finish->reflection_fn = &dmnsn_reflective_finish_fn; + finish->free_fn = &free; - finish->ptr = params; - finish->reflection_fn = &dmnsn_reflective_finish_fn; - finish->free_fn = &free; - } return finish; } diff --git a/libdimension/scene.c b/libdimension/scene.c index 4595afd..dbda90b 100644 --- a/libdimension/scene.c +++ b/libdimension/scene.c @@ -20,37 +20,28 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ #include <unistd.h> /* For sysconf */ /* Allocate an empty scene */ dmnsn_scene * dmnsn_new_scene() { - dmnsn_scene *scene = malloc(sizeof(dmnsn_scene)); - if (scene) { - scene->default_texture = dmnsn_new_texture(); - if (!scene->default_texture) { - dmnsn_delete_scene(scene); - errno = ENOMEM; - return NULL; - } + dmnsn_scene *scene = dmnsn_malloc(sizeof(dmnsn_scene)); - scene->camera = NULL; - scene->canvas = NULL; - scene->objects = dmnsn_new_array(sizeof(dmnsn_object *)); - scene->lights = dmnsn_new_array(sizeof(dmnsn_light *)); - scene->quality = DMNSN_RENDER_FULL; - scene->reclimit = 5; + scene->default_texture = dmnsn_new_texture(); + scene->camera = NULL; + scene->canvas = NULL; + scene->objects = dmnsn_new_array(sizeof(dmnsn_object *)); + scene->lights = dmnsn_new_array(sizeof(dmnsn_light *)); + scene->quality = DMNSN_RENDER_FULL; + scene->reclimit = 5; + + /* Find the number of processors/cores running (TODO: do this portably) */ + int nprocs = sysconf(_SC_NPROCESSORS_ONLN); + if (nprocs < 1) + nprocs = 1; + scene->nthreads = nprocs; - /* Find the number of processors/cores running (TODO: do this portably) */ - int nprocs = sysconf(_SC_NPROCESSORS_ONLN); - if (nprocs < 1) - nprocs = 1; - scene->nthreads = nprocs; - } else { - errno = ENOMEM; - } return scene; } diff --git a/libdimension/solid_pigment.c b/libdimension/solid_pigment.c index a69e25a..e414fc2 100644 --- a/libdimension/solid_pigment.c +++ b/libdimension/solid_pigment.c @@ -20,7 +20,6 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ /* Solid color pigment callback */ static dmnsn_color dmnsn_solid_pigment_fn(const dmnsn_pigment *pigment, @@ -30,21 +29,14 @@ static dmnsn_color dmnsn_solid_pigment_fn(const dmnsn_pigment *pigment, dmnsn_pigment * dmnsn_new_solid_pigment(dmnsn_color color) { - dmnsn_color *solid; dmnsn_pigment *pigment = dmnsn_new_pigment(); - if (pigment) { - solid = malloc(sizeof(dmnsn_color)); - if (!solid) { - dmnsn_delete_pigment(pigment); - errno = ENOMEM; - return NULL; - } - *solid = color; - pigment->pigment_fn = &dmnsn_solid_pigment_fn; - pigment->free_fn = &free; - pigment->ptr = solid; - } + dmnsn_color *solid = dmnsn_malloc(sizeof(dmnsn_color)); + *solid = color; + + pigment->pigment_fn = &dmnsn_solid_pigment_fn; + pigment->free_fn = &free; + pigment->ptr = solid; return pigment; } diff --git a/libdimension/sphere.c b/libdimension/sphere.c index 7c2894b..77fd1d4 100644 --- a/libdimension/sphere.c +++ b/libdimension/sphere.c @@ -19,7 +19,6 @@ *************************************************************************/ #include "dimension.h" -#include <stdlib.h> /* For malloc */ #include <math.h> /* For sqrt */ /* @@ -39,12 +38,10 @@ dmnsn_object * dmnsn_new_sphere() { dmnsn_object *sphere = dmnsn_new_object(); - if (sphere) { - sphere->intersection_fn = &dmnsn_sphere_intersection_fn; - sphere->inside_fn = &dmnsn_sphere_inside_fn; - sphere->bounding_box.min = dmnsn_new_vector(-1.0, -1.0, -1.0); - sphere->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 1.0); - } + sphere->intersection_fn = &dmnsn_sphere_intersection_fn; + sphere->inside_fn = &dmnsn_sphere_inside_fn; + sphere->bounding_box.min = dmnsn_new_vector(-1.0, -1.0, -1.0); + sphere->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 1.0); return sphere; } diff --git a/libdimension/texture.c b/libdimension/texture.c index 28f5033..7feb0e0 100644 --- a/libdimension/texture.c +++ b/libdimension/texture.c @@ -20,18 +20,13 @@ #include "dimension.h" #include <errno.h> -#include <stdlib.h> /* For malloc */ /* Allocate a dummy pigment */ dmnsn_pigment * dmnsn_new_pigment() { - dmnsn_pigment *pigment = malloc(sizeof(dmnsn_pigment)); - if (pigment) { - pigment->free_fn = NULL; - } else { - errno = ENOMEM; - } + dmnsn_pigment *pigment = dmnsn_malloc(sizeof(dmnsn_pigment)); + pigment->free_fn = NULL; return pigment; } @@ -51,16 +46,12 @@ dmnsn_delete_pigment(dmnsn_pigment *pigment) dmnsn_finish * dmnsn_new_finish() { - dmnsn_finish *finish = malloc(sizeof(dmnsn_finish)); - if (finish) { - finish->diffuse_fn = NULL; - finish->specular_fn = NULL; - finish->ambient_fn = NULL; - finish->reflection_fn = NULL; - finish->free_fn = NULL; - } else { - errno = ENOMEM; - } + dmnsn_finish *finish = dmnsn_malloc(sizeof(dmnsn_finish)); + finish->diffuse_fn = NULL; + finish->specular_fn = NULL; + finish->ambient_fn = NULL; + finish->reflection_fn = NULL; + finish->free_fn = NULL; return finish; } @@ -80,13 +71,9 @@ dmnsn_delete_finish(dmnsn_finish *finish) dmnsn_texture * dmnsn_new_texture() { - dmnsn_texture *texture = malloc(sizeof(dmnsn_texture)); - if (texture) { - texture->pigment = NULL; - texture->finish = NULL; - } else { - errno = ENOMEM; - } + dmnsn_texture *texture = dmnsn_malloc(sizeof(dmnsn_texture)); + texture->pigment = NULL; + texture->finish = NULL; return texture; } |