src/lib/ctx.c
author Tero Marttila <terom@fixme.fi>
Tue, 26 Jan 2010 21:22:43 +0200
changeset 123 81d1cad8b588
parent 33 0ed40e11b0e8
permissions -rw-r--r--
docfix README for new Makefile
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#include "ctx.h"
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include "error.h"
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
     3
#include "shared/log.h"
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include <stdlib.h>
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
#include <signal.h>
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
#include <assert.h>
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
#include <stdio.h> // for perror
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
21
Tero Marttila <terom@fixme.fi>
parents: 20
diff changeset
    10
/**
Tero Marttila <terom@fixme.fi>
parents: 20
diff changeset
    11
 * Wrapper around pthread_mutex_unlock for use with pthread_cleanup_push
Tero Marttila <terom@fixme.fi>
parents: 20
diff changeset
    12
 */
20
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    13
static void pt_mutex_unlock (void *arg)
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    14
{
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    15
    pthread_mutex_t *mutex = arg;
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    16
    
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    17
    log_debug("cleanup");
20
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    18
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    19
    assert(!pthread_mutex_unlock(mutex));
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    20
}
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    21
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
/**
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
 * Enqueue the given piece of work
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
 *
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
 * This function always succeeds.
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
 */
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
static void pt_work_enqueue (struct pt_ctx *ctx, struct pt_work *work)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
    // acquire
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
    assert(!pthread_mutex_lock(&ctx->work_mutex));
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
    // enqueue work
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
    TAILQ_INSERT_TAIL(&ctx->work, work, ctx_work);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    // if there's a thread waiting, wake one up. Otherwise, some thread will find it once it finishes its current work
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
    assert(!pthread_cond_signal(&ctx->work_cond));
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
    // release 
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
    assert(!pthread_mutex_unlock(&ctx->work_mutex));
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
/**
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    43
 * Dequeue a piece of work, returning true while there was still work to do
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
 */
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    45
static bool pt_work_dequeue (struct pt_ctx *ctx, struct pt_work **work_ptr)
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
{
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    47
    bool ret;
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    48
20
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    49
    // acquire, cancel-safe
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    50
    pthread_cleanup_push(pt_mutex_unlock, &ctx->work_mutex);
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
    assert(!pthread_mutex_lock(&ctx->work_mutex));
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    // wait for work
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    54
    while (ctx->running && TAILQ_EMPTY(&ctx->work))
20
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    55
        // we can expect to get pthread_cancel'd here
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
        assert(!pthread_cond_wait(&ctx->work_cond, &ctx->work_mutex));
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    57
    
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    58
    // still got work?
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    59
    if (!TAILQ_EMPTY(&ctx->work)) {
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    60
        // pop work
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    61
        *work_ptr = TAILQ_FIRST(&ctx->work);
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    62
        TAILQ_REMOVE(&ctx->work, *work_ptr, ctx_work);
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    64
        log_debug("got work");
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    65
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    66
        ret = true;
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    67
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    68
    } else {
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    69
        assert(!ctx->running);
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    70
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    71
        // work empty, idle
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    72
        assert(!pthread_cond_signal(&ctx->idle_cond));
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    73
        
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    74
        log_debug("idle/dead");
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    75
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    76
        // no more work
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    77
        ret = false;
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    78
    }
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    // release
20
f0d1011e8874 cleanup mutex when cancel'd in pthread_cond_wait
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    81
    pthread_cleanup_pop(true);
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    82
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    83
    return ret;
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
/**
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    87
 * Wait for work queue to empty and workers to finish
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
 */
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    89
static void pt_work_shutdown (struct pt_ctx *ctx)
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
    // acquire
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
    assert(!pthread_mutex_lock(&ctx->work_mutex));
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
    
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    94
    // indicate to terminate
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    95
    ctx->running = false;
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    96
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    97
    // wake up any idle workers
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    98
    assert(!pthread_cond_broadcast(&ctx->work_cond));
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    99
    
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
    // wait for it to drain...
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
    while (!TAILQ_EMPTY(&ctx->work))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
        assert(!pthread_cond_wait(&ctx->idle_cond, &ctx->work_mutex));
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
    // release
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
    assert(!pthread_mutex_unlock(&ctx->work_mutex));
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
/**
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
 * Execute a piece of work
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
 */
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
static void pt_work_execute (struct pt_work *work)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
    work->func(work->arg);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
/**
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
 * Release work state once done
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
 */
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
static void pt_work_release (struct pt_work *work)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    free(work);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
/**
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
 * Worker thread entry point
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
 */
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
static void* pt_thread_main (void *arg)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
    struct pt_thread *thread = arg;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
    struct pt_work *work;
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   131
    
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   132
    log_debug("start");
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    // if only life were so simple...
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   135
    while (pt_work_dequeue(thread->ctx, &work)) {
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   136
        log_debug("work_execute");
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
        pt_work_execute(work);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        pt_work_release(work);
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   139
        log_debug("work_done");
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
    }
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   142
    log_debug("exit");
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   143
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
    return NULL;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
/**
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
 * Shut down a pt_thread, waiting for it to finish.
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
 *
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
 * Does not remove the thread from the pool or release the pt_thread.
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
 */
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
static void pt_thread_shutdown (struct pt_thread *thread)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
{
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   154
    // wait for it to finish
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
    if (pthread_join(thread->tid, NULL))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
        perror("pthread_join");
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    // mark
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    thread->tid = 0;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
/**
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
 * Release pt_thread state, aborting thread if running.
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
 *
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
 * This is guaranteed to remove the thread from the ctx_threads if it was added.
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
 */
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
static void pt_thread_destroy (struct pt_thread *thread)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
    if (thread->tid) {
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
        // detach
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
        if (pthread_detach(thread->tid))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
            perror("pthread_detach");
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
        // abort thread
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
        if (pthread_kill(thread->tid, SIGTERM))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
            perror("pthread_detach");
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
    }
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
        
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
    // remove from pool
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
    TAILQ_REMOVE(&thread->ctx->threads, thread, ctx_threads);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
    
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
    free(thread);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
/**
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
 * Start a new thread and add it to the thread pool
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
 */
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
static int pt_ctx_add_thread (struct pt_ctx *ctx)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
    struct pt_thread *thread;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
    int err;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
    // alloc
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
    if ((thread = calloc(1, sizeof(*thread))) == NULL)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
        return -PT_ERR_MEM;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
    // init
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
    thread->ctx = ctx;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
    // start thread, default attrs
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
    if (pthread_create(&thread->tid, NULL, pt_thread_main, thread))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
        JUMP_SET_ERROR(err, PT_ERR_PTHREAD_CREATE);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
    // add to pool
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
    TAILQ_INSERT_TAIL(&ctx->threads, thread, ctx_threads);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
    // ok
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
    return 0;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
error:
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
    // drop, don't try and remove from tailq...
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
    free(thread);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
    return err;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
int pt_ctx_new (struct pt_ctx **ctx_ptr, int threads)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
    struct pt_ctx *ctx;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
    int err;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
    // alloc
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
    if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
        return -PT_ERR_MEM;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
    // init
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
    TAILQ_INIT(&ctx->threads);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
    TAILQ_INIT(&ctx->work);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
    pthread_mutex_init(&ctx->work_mutex, NULL);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
    pthread_cond_init(&ctx->work_cond, NULL);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
    pthread_cond_init(&ctx->idle_cond, NULL);
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   234
    ctx->running = true;
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
    // start threadpool
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
    for (int i = 0; i < threads; i++) {
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
        if ((err = pt_ctx_add_thread(ctx)))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
            JUMP_ERROR(err);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
    }
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
    // ok
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
    *ctx_ptr = ctx;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
    return 0;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
        
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
error:
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
    // cleanup
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
    pt_ctx_destroy(ctx);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
    return err;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
int pt_ctx_work (struct pt_ctx *ctx, pt_work_func func, void *arg)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
    struct pt_work *work;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   257
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
    // check state
21
Tero Marttila <terom@fixme.fi>
parents: 20
diff changeset
   259
    // XXX: this is kind of retarded, because pt_ctx_shutdown/work should only be called from the same thread...
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
    if (!ctx->running)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
        RETURN_ERROR(PT_ERR_CTX_SHUTDOWN);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
21
Tero Marttila <terom@fixme.fi>
parents: 20
diff changeset
   263
    // alloc
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
    if ((work = calloc(1, sizeof(*work))) == NULL)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
        RETURN_ERROR(PT_ERR_MEM);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   267
    // init
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
    work->func = func;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
    work->arg = arg;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   270
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   271
    // enqueue
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   272
    pt_work_enqueue(ctx, work);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   274
    // ok
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
    return 0;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
int pt_ctx_shutdown (struct pt_ctx *ctx)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   280
    struct pt_thread *thread;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   281
33
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   282
    // finish work
0ed40e11b0e8 don't use pthread_cancel to shutdown threads, it doesn't work...
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   283
    pt_work_shutdown(ctx);
19
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   284
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   285
    // shut down each thread
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
    TAILQ_FOREACH(thread, &ctx->threads, ctx_threads)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
        // XXX: handle errors of some kind?
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   288
        pt_thread_shutdown(thread);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   289
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
    // then drop
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   291
    pt_ctx_destroy(ctx);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   292
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   293
    return 0;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   294
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   295
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   296
void pt_ctx_destroy (struct pt_ctx *ctx)
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   297
{
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   298
    struct pt_thread *thread;
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   299
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   300
    // kill threads
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   301
    while ((thread = TAILQ_FIRST(&ctx->threads)))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   302
        pt_thread_destroy(thread);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   303
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   304
    // destroy mutex/conds
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   305
    if (pthread_cond_destroy(&ctx->idle_cond))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
        perror("pthread_cond_destroy(idle_cond)");
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   307
    
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   308
    if (pthread_cond_destroy(&ctx->work_cond))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
        perror("pthread_cond_destroy(work_cond)");
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   310
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   311
    if (pthread_mutex_destroy(&ctx->work_mutex))
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   312
        perror("pthread_mutex_destroy(work_mutex)");
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   313
   
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   314
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   315
    free(ctx);
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   316
}
ebcc49de97d0 implement pt_ctx threadpool and pt_image_tile_async
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   317