/ani/mrses

To get this branch, use:
bzr branch http://darksoft.org/webbzr/ani/mrses
1 by Suren A. Chilingaryan
Initial import
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
}