render_threads.c
author Tero Marttila <terom@fixme.fi>
Tue, 17 Jun 2008 16:39:55 +0300
changeset 19 d18606bb6f20
child 20 7512207c9041
permissions -rw-r--r--
a working threaded sliced render, plus modifications to other modules to use this in web_main

committer: Tero Marttila <terom@fixme.fi>
19
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#include <stdlib.h>
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include <assert.h>
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
#include <pthread.h>
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
#include "common.h"
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
#include "render_threads.h"
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
#include "render_slices_struct.h"
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
#include "render_mandelbrot.h"
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
/*
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
 * Render a mandelbrot in several slices simultaneously using threads. 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
 * This works as an n:1 producer-consumer model, where we have n worker threads
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
 * rendering n slices, and one manager thread that processes the completed rows.
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
 * 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
 * The worker threads function by first rendering a row of pixel data into memory,
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
 * and then calling a function that will do something with that completed segment.
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
 *  
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
 *  * clear the can_continue marker, because the real value may change depending
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
 *    on what our segment does, and we don't want stale values from before we
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
 *    processed thse segment in it
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
 *      * process the segment
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
 *  * if the segment didn't complete a row, wait until some worker thread submits
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
 *    a segment that does, or the manager thread processes a row
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
 *      * if noone has signaled the cond in between us deciding what to do with
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
 *        the segment and this step,
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
 *          * wait on the cond
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
 *      * we can proceed to render the next segment
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
 *          * we should now be marked as continueable
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
 *  * if the segment completed a row, the manager thread needs to process this
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
 *    newly completed row. 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
 *      * if we can also continue on to the next row without waiting for the manager
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
 *        to process the row we just filled
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
 *          * mark all the segments as continueable
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
 *          * signal the cond the threads may be waiting on
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
 *      * increment the waiting_rows counter
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
 *          * signal the manager in case it's waiting
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
 *      * else, if noone has signaled the continue cond after we processed the
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
 *        segment,
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
 *          * wait on the cond
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
 *      * we can proceed to render the next segment
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
 *          * we should now be marked as continueable
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
 * * if we have no more segments to submit
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
 *      * update the slices_running counter
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
 *          * if the counter is now zero (we were the last slice to complete)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
 *              * signal the manager thread that it doesn't need to wait anymore
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
 * The manager thread just sits in a loop calling process_row until all the slices
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
 * have completed.
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
 * * if no workers have updated the waiting_rows counter since we last processed
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
 *   a row, and the slices_running counter isn't zero (we still have threads
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
 *   running)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
 *      * wait on a cond until something happens
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
 * * if waiting_rows is nonzero
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
 *      * decrement it
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
 *      * process a row
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
 *      * if processing the row means that waiting slices can continue
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
 *          * mark all the segments as continueable
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
 *          * signal the cond the threads may be waiting on
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
 * * if slices_running is zero
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
 *      * break out of the loop
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
 *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
 * * otherwise, go back to the start again
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
 */     
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
struct render_threads {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
    // do I need to free this?
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
    int owned_by_me;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    // info for the induvidual threads
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
    struct render_thread {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
        // the slice that we need to render
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
        struct render_slice_info *slice_info;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
        // our thread id
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
        pthread_t thread;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
        // how many times we are allowed to continue now
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
        int can_continue;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
        // how many segments we've written
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
        int segments_done;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
        // ptr back to ctx
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
        struct render_threads *self;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
    } threads[RENDER_SLICES_MAX];
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
    // the render_slices struct
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
    struct render_slices slices_info;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
    // the manager thread id
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
    pthread_t manager_thread;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    // how many slices?
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    int slice_count;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
    /*
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
     * The worker threads must be careful to wait for the manager thread to start running before they attempt to signal
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
     * the process_row_cond. This is done via this flag, in conjunction with continue_{cond,mut}. 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
     *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
     * Workers should lock continue_mut, and if this flag is zero, wait on continue_cond (releasing the mutex). If the
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
     * flag is already nonzero, the worker threads do not need to cond_wait and can just continue.
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
     *
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
     * On startup, the manager thread will lock continue_mut, set this to nonzero, signal continue_cond, and unlock
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
     * continue_mut as normal.
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
     */
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
    int manager_running;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
    /*
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
     * Signals to the manager
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
     */
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
    int slices_running;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    int waiting_rows;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
    /* the inter-thread communication stuff */
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
    // the worker threads signal this when their segment_done call indicates that the manager thread should call
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
    // process_row now.
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
    pthread_cond_t process_row_cond;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
    pthread_mutex_t process_row_mut;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
    // the worker threads and the manager thread signal this when segment_done or process_row indicate that the worker
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
    // threads should call segment_done again. Worker threads that receive ~SLICE_CONTINUE from segment_done will wait
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
    // on this cond.
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
    pthread_cond_t continue_cond;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    pthread_mutex_t continue_mut;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
    // used to protect slices_info
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
    pthread_mutex_t slices_mut;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
};
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
void render_threads_deinit (struct render_threads *ctx) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
    render_slices_deinit(&ctx->slices_info);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
}
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
void render_threads_free (struct render_threads *ctx) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
    render_threads_deinit(ctx);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
    if (ctx->owned_by_me)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
        free(ctx);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
}
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
int _render_threads_slice_row (void *arg, unsigned char *rowbuf) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
    struct render_thread *subctx = arg;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
    int status, i;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
    // we need to handle the render_slices state atomically, so lock it
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
    pthread_mutex_lock(&subctx->self->slices_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
    pthread_mutex_lock(&subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    // make sure that we don't have any stale state in this
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    subctx->can_continue = 0;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
    // process the segment
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    status = render_slices_segment_done(&subctx->self->slices_info, subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
    // debugging
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
/*    subctx->segments_done++;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
    printf("slice %zu: segment_done, status=(%s %s), row=%d\n", subctx->slice_info->index,
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
        status & SLICE_PROCESS_ROW ? "SLICE_PROCESS_ROW" : "", 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
        status & SLICE_CONTINUE ? "SLICE_CONTINUE" : "",
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
        subctx->segments_done
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
    );
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
*/
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    // done with the slices stuff
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
    pthread_mutex_unlock(&subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
    pthread_mutex_unlock(&subctx->self->slices_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
    // do we need to notify the other worker threads?
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
    if (status & SLICE_CONTINUE) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
        pthread_mutex_lock(&subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
//        printf("slice %zu: signal continue\n", subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
        // mark them as continueable
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
        for (i = 0; i < subctx->self->slice_count; i++)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
            subctx->self->threads[i].can_continue = 1;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
        // signal then to continue
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
        pthread_cond_broadcast(&subctx->self->continue_cond);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
        pthread_mutex_unlock(&subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
    }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
    // tell the manager thread that it can process a row
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
    if (status & SLICE_PROCESS_ROW) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
        // grab the process_row lock so that we can do stuff with it
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
        pthread_mutex_lock(&subctx->self->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
        
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
        // tell it that it has a row waiting
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
        subctx->self->waiting_rows++;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
        // signal it in case it was waiting
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
        pthread_cond_signal(&subctx->self->process_row_cond);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
        // release the process_row mutex
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
        pthread_mutex_unlock(&subctx->self->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
    }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
    // handle our can-continue status
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
    pthread_mutex_lock(&subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
    if (status & SLICE_CONTINUE) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
        // don't wait for anything, we can just continue right away
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
//        printf("slice %zu: direct continue\n", subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
    } else {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
        if (!subctx->can_continue) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
            // we need to wait until someone signals it
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
//            printf("slice %zu: waiting...\n", subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
            pthread_cond_wait(&subctx->self->continue_cond, &subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
//            printf("slice %zu: continue after wait\n", subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
        } else {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
            // no need to wait, because someone else took care of that before we got a chance to wait
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
//            printf("slice %zu: indirect continue\n", subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
         
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
        }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
    }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
    // we should now be marked as continueable
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
    assert(subctx->can_continue);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
    // proceed to continue, so clear this
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
    subctx->can_continue = 0;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
    // done handling the continue state
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
    pthread_mutex_unlock(&subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
    // row handled succesfully
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
    return 0;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
}
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
void *_render_threads_slice_func (void *arg) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
    struct render_thread *subctx = arg;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
    // set up the render_info to render into local memory using the address provided via slice_info
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
    // use _render_threads_slice_row to handle the completed rows
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
    if (render_local_mem(subctx->slice_info->render_info, 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
        &subctx->slice_info->render_buf, 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
        &_render_threads_slice_row, subctx)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
    )
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
        goto error;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
   
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
    // wait for the manager to start up
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   257
    pthread_mutex_lock(&subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
    if (!subctx->self->manager_running)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
        pthread_cond_wait(&subctx->self->continue_cond, &subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
    pthread_mutex_unlock(&subctx->self->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
    // start rendering...
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   263
//    printf("slice %zu: start\n", subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
    if (render_mandelbrot(subctx->slice_info->render_info))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
        goto error;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   267
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
    // success, slice render complete
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
//    printf("slice %zu: done\n", subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   270
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   271
    // sanity checks
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   272
    assert(subctx->self->slices_running > 0);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   274
    pthread_mutex_lock(&subctx->self->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
    if (--subctx->self->slices_running == 0) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
        // this was the last row, send the manager a final signal in case it's waiting
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
//        printf("slice %zu: signal\n", subctx->slice_info->index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
        pthread_cond_signal(&subctx->self->process_row_cond);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   280
    }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   281
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
    pthread_mutex_unlock(&subctx->self->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   283
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   284
    // successful exit
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   285
    pthread_exit(NULL);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
error:
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   288
    /* XXX: signal an error condition? Mind, with the current code, this should never happen... */
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   289
    FATAL("a render thread failed somehow, taking down the rest of the daemon application as well");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
}
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   291
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   292
void *_render_threads_manager_func (void *arg) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   293
    struct render_threads *ctx = arg;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   294
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   295
    // the process_row return status
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   296
    int status, i;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   297
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   298
    // first, mark us as running and signal any waiting workers
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   299
    pthread_mutex_lock(&ctx->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   300
    ctx->manager_running = 1;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   301
    pthread_cond_broadcast(&ctx->continue_cond);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   302
    pthread_mutex_unlock(&ctx->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   303
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   304
    // needs to be locked inside the loop
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   305
    pthread_mutex_lock(&ctx->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   307
    // then we wait around and call process_row when told to
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   308
    do {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
        // the process_row must be locked here
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   310
//        printf("manager: to wait\n");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   311
        
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   312
        // figure out if we need to wait
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   313
        if (ctx->waiting_rows == 0 && ctx->slices_running > 0) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   314
            // no work to do right now, so wait for some
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   315
//            printf("manager: waiting\n");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   316
            
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   317
            // wait until a worker thread signals us
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   318
            pthread_cond_wait(&ctx->process_row_cond, &ctx->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   319
        }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   320
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   321
        // make sure we actually have something to do now...
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   322
        assert(ctx->waiting_rows > 0 || ctx->slices_running == 0);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   323
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   324
        // keep the process_row mutex locked until we've inspected/updated both vars
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   325
        
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   326
        // do we need to process a row?
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   327
        if (ctx->waiting_rows > 0) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   328
            // claim the row for ourself
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   329
            ctx->waiting_rows--;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   330
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   331
            // unlock the process_row mut while we handle this row
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   332
            pthread_mutex_unlock(&ctx->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   333
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   334
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   335
            // keep calls to render_slices synchronized
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   336
            pthread_mutex_lock(&ctx->slices_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   337
            
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   338
            // call into render_slices
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   339
            status = render_slices_process_row(&ctx->slices_info);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   340
            
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   341
/*            printf("manager: did process_row, status=(%s %s)\n", 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   342
                status & SLICE_PROCESS_ROW ? "SLICE_PROCESS_ROW" : "", 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   343
                status & SLICE_CONTINUE ? "SLICE_CONTINUE" : ""
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   344
            );
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   345
*/            
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   346
            
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   347
            // done with render_slices
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   348
            pthread_mutex_unlock(&ctx->slices_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   349
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   350
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   351
            // any errors?
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   352
            if (status == -1) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   353
                goto error;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   354
            }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   355
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   356
            // can any waiting slices now continue?
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   357
            if (status & SLICE_CONTINUE) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   358
                // grab the continue_mut lock while we update this state
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   359
                pthread_mutex_lock(&ctx->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   360
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   361
                // increment continue_count for all slices
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   362
                for (i = 0; i < ctx->slice_count; i++)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   363
                    ctx->threads[i].can_continue = 1;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   364
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   365
//                printf("manager: signal continue\n");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   366
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   367
                // signal any waiting worker threads to continue, giving them a chance to call cond_wait first.
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   368
                pthread_cond_broadcast(&ctx->continue_cond);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   369
                
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   370
                // done with that
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   371
                pthread_mutex_unlock(&ctx->continue_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   372
            }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   373
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   374
            // XXX: ignore SLICE_PROCESS_ROW
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   375
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   376
            // grab our mutex again
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   377
            pthread_mutex_lock(&ctx->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   378
        }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   379
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   380
        // are all the slices done now?
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   381
        if (ctx->slices_running == 0) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   382
            // unlock the mutex so the worker threads don't get stuck on it
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   383
            pthread_mutex_unlock(&ctx->process_row_mut);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   384
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   385
            break;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   386
        }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   387
        
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   388
        // keep the process_row mutex locked at the top of the loop 
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   389
    } while (1);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   390
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   391
    // all slices are done now
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   392
    if (render_slices_done(&ctx->slices_info))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   393
        goto error;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   394
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   395
//    printf("manager: done\n");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   396
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   397
    // reap all the workers
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   398
    void *retval;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   399
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   400
    for (i = 0; i < ctx->slice_count; i++) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   401
        if (pthread_join(ctx->threads[i].thread, &retval))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   402
            PERROR("pthread_join");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   403
        
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   404
        // XXX: assume they don't get canceled (SIGSEV etc?)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   405
        assert(retval == NULL);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   406
    }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   407
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   408
    // ok, exit ourself
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   409
    pthread_exit(NULL);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   410
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   411
error:
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   412
    /* XXX: handle errors gracefully... */
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   413
    FATAL("the threaded render operation failed, taking down the rest of the daemon application as well...");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   414
}
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   415
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   416
int render_threads_init (struct render_threads *ctx, struct render *render_info) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   417
    // break the render operation down into induvidual slices
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   418
    if (render_slices_init(&ctx->slices_info, render_info))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   419
        goto error;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   420
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   421
    // init the mutexes (this should never fail)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   422
    assert(!(
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   423
            pthread_mutex_init(&ctx->process_row_mut, NULL)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   424
         || pthread_mutex_init(&ctx->continue_mut, NULL)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   425
         || pthread_mutex_init(&ctx->slices_mut, NULL)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   426
    ));
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   427
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   428
    // init the conds (this should never fail)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   429
    assert(!(
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   430
            pthread_cond_init(&ctx->process_row_cond, NULL)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   431
         || pthread_cond_init(&ctx->continue_cond, NULL)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   432
    ));
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   433
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   434
    // how many slices?
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   435
    ctx->slices_running = ctx->slice_count = render_slices_get_count(&ctx->slices_info);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   436
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   437
    // spawn a thread for each slice
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   438
    int index;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   439
    for (index = 0; index < ctx->slice_count; index++) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   440
        // the self ptr...
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   441
        ctx->threads[index].self = ctx;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   442
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   443
        // fetch the slice info
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   444
        ctx->threads[index].slice_info = render_slices_get_slice_info(&ctx->slices_info, index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   445
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   446
        // spawn the thread
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   447
        if (pthread_create(&ctx->threads[index].thread, NULL, &_render_threads_slice_func, &ctx->threads[index]))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   448
            PERROR("pthread_create(slice_func:%d)", index);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   449
    }
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   450
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   451
    // init the attrs for the manager thread
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   452
    pthread_attr_t manager_attrs;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   453
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   454
    if (
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   455
            pthread_attr_init(&manager_attrs)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   456
//         || pthread_setdetachstate(&manager_attrs, PTHREAD_CREATE_DETACHED)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   457
    )
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   458
        PERROR("pthread_attr_init/pthread_attr_setdetachstate");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   459
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   460
    // spawn the manager thread
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   461
    if (pthread_create(&ctx->manager_thread, &manager_attrs, &_render_threads_manager_func, ctx))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   462
        PERROR("pthread_create(manager_func)");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   463
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   464
    // success
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   465
    return 0;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   466
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   467
error:
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   468
    render_threads_deinit(ctx);
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   469
    return -1;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   470
}
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   471
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   472
struct render_threads *render_threads_alloc (struct render *render_info) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   473
    struct render_threads *ctx = NULL;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   474
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   475
    if (!(ctx = calloc(1, sizeof(*ctx))))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   476
        ERROR("calloc");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   477
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   478
    // init with silent fall-through
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   479
    if (render_threads_init(ctx, render_info))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   480
        goto error;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   481
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   482
    // success
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   483
    return ctx;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   484
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   485
error:
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   486
    return NULL;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   487
}
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   488
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   489
int render_threads_wait (struct render_threads *ctx) {
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   490
    void *retval;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   491
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   492
    if (pthread_join(ctx->manager_thread, &retval))
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   493
        PERROR("pthread_join");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   494
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   495
    if (retval == PTHREAD_CANCELED)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   496
        ERROR("manager thread was canceled");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   497
    else if (retval != NULL)
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   498
        ERROR("manager thread exited with unknown return value");
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   499
    
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   500
    // ok, success
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   501
    return 0;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   502
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   503
error:
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   504
    // caller needs to free ctx
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   505
    return -1;
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   506
}
d18606bb6f20 a working threaded sliced render, plus modifications to other modules to use this in web_main
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   507