summaryrefslogtreecommitdiffstats
path: root/libdimension/raytrace.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-04-07 14:26:15 -0400
committerTavian Barnes <tavianator@gmail.com>2010-04-07 14:34:52 -0400
commit2b087cb45ae91f90492a935625570d7d42ee3ecb (patch)
treea464213b08d04c8c91c8879a84e534f895c84378 /libdimension/raytrace.c
parent7d6663eeb68bf9d0a3dff86128827c0c1d85df69 (diff)
downloaddimension-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/raytrace.c')
-rw-r--r--libdimension/raytrace.c125
1 files changed, 37 insertions, 88 deletions
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)