/ani/mrses

To get this branch, use:
bzr branch http://suren.me/webbzr/ani/mrses

« back to all changes in this revision

Viewing changes to cell/hw_thread.c

  • Committer: Suren A. Chilingaryan
  • Date: 2010-04-28 04:30:08 UTC
  • Revision ID: csa@dside.dyndns.org-20100428043008-vd9z0nso9axezvlp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <pthread.h>
 
5
#include <errno.h>
 
6
 
 
7
#include "hw_thread.h"
 
8
 
 
9
static void *hw_thread_function(HWThread ctx) {
 
10
    int err;
 
11
    int chunk_id;
 
12
    
 
13
    HWRunFunction *runs;
 
14
    HWRunFunction run;
 
15
    HWSched sched;
 
16
    void *hwctx;
 
17
    
 
18
    sched = ctx->sched;
 
19
    runs = ctx->run;
 
20
    hwctx = ctx->hwctx;
 
21
    
 
22
    hw_sched_lock(sched, job_cond);
 
23
 
 
24
    hw_sched_lock(sched, compl_cond);
 
25
    ctx->status = HW_THREAD_STATUS_IDLE;    
 
26
    hw_sched_broadcast(sched, compl);
 
27
    hw_sched_unlock(sched, compl_cond);
 
28
    
 
29
    while (sched->status) {
 
30
        hw_sched_wait(sched, job);
 
31
        if (!sched->status) break;
 
32
 
 
33
        hw_sched_unlock(sched, job_cond);
 
34
        
 
35
        run = runs[sched->entry];
 
36
        chunk_id = hw_sched_get_chunk(sched, ctx->thread_id);
 
37
 
 
38
            /* Should be after get_chunk, since we can check if it's first time */
 
39
        ctx->status = HW_THREAD_STATUS_RUNNING; 
 
40
        while (chunk_id >= 0) {
 
41
            err = run(ctx, hwctx, chunk_id, sched->ctx);
 
42
            if (err) {
 
43
                fprintf(stderr, "Error exectuing code, %i\n", err);
 
44
                pthread_exit(NULL);
 
45
            }
 
46
            chunk_id = hw_sched_get_chunk(sched, ctx->thread_id);
 
47
        }
 
48
 
 
49
        hw_sched_lock(sched, job_cond);
 
50
        
 
51
        hw_sched_lock(sched, compl_cond);
 
52
        ctx->status = HW_THREAD_STATUS_DONE;
 
53
        hw_sched_broadcast(sched, compl);
 
54
        hw_sched_unlock(sched, compl_cond);
 
55
    }
 
56
 
 
57
    hw_sched_unlock(sched, job_cond);
 
58
 
 
59
    pthread_exit(NULL);
 
60
}
 
61
 
 
62
HWThread hw_thread_create(HWSched sched, int thread_id, void *hwctx, HWRunFunction *run_func, HWFreeFunction free_func) {
 
63
    int err;
 
64
    
 
65
    HWThread ctx;
 
66
    
 
67
    ctx = (HWThread)malloc(sizeof(HWThreadS));
 
68
    if (!ctx) return ctx;
 
69
    
 
70
    memset(ctx, 0, sizeof(HWThreadS));
 
71
 
 
72
    ctx->sched = sched;
 
73
    ctx->hwctx = hwctx;
 
74
    ctx->run = run_func;
 
75
    ctx->free = free_func;
 
76
    ctx->thread_id = thread_id;
 
77
    ctx->status = HW_THREAD_STATUS_INIT;
 
78
    
 
79
    err = pthread_create(&ctx->thread, NULL, (void*(*)(void*))hw_thread_function, ctx);
 
80
    if (err) {
 
81
        fprintf(stderr, "Error spawn thread, errno: %i\n", errno);
 
82
        hw_thread_destroy(ctx);
 
83
        return NULL;
 
84
    }
 
85
    
 
86
    return ctx;
 
87
}
 
88
 
 
89
void hw_thread_destroy(HWThread ctx) {
 
90
    if (ctx->thread) {
 
91
        pthread_join(ctx->thread, NULL);
 
92
    }
 
93
    
 
94
    if (ctx->data) {
 
95
        free(ctx->data);
 
96
    }
 
97
    
 
98
    if (ctx->free) {
 
99
        ctx->free(ctx->hwctx);
 
100
    }
 
101
    
 
102
    free(ctx);
 
103
}