Commit 6afe2329 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

added cdo_task

parent 76e71e62
......@@ -518,6 +518,8 @@ src/cdo_getopt.h -text
src/cdo_history.c -text
src/cdo_int.h -text
src/cdo_pthread.c -text
src/cdo_task.c -text
src/cdo_task.h -text
src/cdo_vlist.c -text
src/cdotest.c -text
src/cellsearchorder.h -text
......
......@@ -7,6 +7,8 @@ libcdo_la_SOURCES = \
cdo_vlist.c \
cdo_getopt.c \
cdo_getopt.h \
cdo_task.c \
cdo_task.h \
cdo_history.c \
after_sptrans.c \
after_fctrans.c \
......
......@@ -124,19 +124,20 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
libcdo_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
am_libcdo_la_OBJECTS = libcdo_la-cdo_pthread.lo libcdo_la-cdo_vlist.lo \
libcdo_la-cdo_getopt.lo libcdo_la-cdo_history.lo \
libcdo_la-after_sptrans.lo libcdo_la-after_fctrans.lo \
libcdo_la-after_dvtrans.lo libcdo_la-after_vertint.lo \
libcdo_la-after_namelist.lo libcdo_la-afterburnerlib.lo \
libcdo_la-constants.lo libcdo_la-color.lo \
libcdo_la-commandline.lo libcdo_la-datetime.lo \
libcdo_la-ecacore.lo libcdo_la-ecautil.lo \
libcdo_la-exception.lo libcdo_la-expr.lo libcdo_la-expr_lex.lo \
libcdo_la-expr_yacc.lo libcdo_la-features.lo \
libcdo_la-field.lo libcdo_la-field2.lo libcdo_la-fieldc.lo \
libcdo_la-fieldmem.lo libcdo_la-fieldmer.lo \
libcdo_la-fieldzon.lo libcdo_la-gradsdeslib.lo \
libcdo_la-grid.lo libcdo_la-grid_area.lo libcdo_la-grid_gme.lo \
libcdo_la-cdo_getopt.lo libcdo_la-cdo_task.lo \
libcdo_la-cdo_history.lo libcdo_la-after_sptrans.lo \
libcdo_la-after_fctrans.lo libcdo_la-after_dvtrans.lo \
libcdo_la-after_vertint.lo libcdo_la-after_namelist.lo \
libcdo_la-afterburnerlib.lo libcdo_la-constants.lo \
libcdo_la-color.lo libcdo_la-commandline.lo \
libcdo_la-datetime.lo libcdo_la-ecacore.lo \
libcdo_la-ecautil.lo libcdo_la-exception.lo libcdo_la-expr.lo \
libcdo_la-expr_lex.lo libcdo_la-expr_yacc.lo \
libcdo_la-features.lo libcdo_la-field.lo libcdo_la-field2.lo \
libcdo_la-fieldc.lo libcdo_la-fieldmem.lo \
libcdo_la-fieldmer.lo libcdo_la-fieldzon.lo \
libcdo_la-gradsdeslib.lo libcdo_la-grid.lo \
libcdo_la-grid_area.lo libcdo_la-grid_gme.lo \
libcdo_la-grid_lcc.lo libcdo_la-grid_rot.lo \
libcdo_la-gridreference.lo libcdo_la-griddes.lo \
libcdo_la-griddes_h5.lo libcdo_la-griddes_nc.lo \
......@@ -556,16 +557,16 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LTLIBRARIES = libcdo.la
libcdo_la_SOURCES = cdo_int.h compare.h cdo_pthread.c cdo_vlist.c \
cdo_getopt.c cdo_getopt.h cdo_history.c after_sptrans.c \
after_fctrans.c after_dvtrans.c after_vertint.c \
after_vertint.h after_namelist.c afterburnerlib.c \
afterburner.h vct_l191.h constants.h constants.c color.c \
color.h commandline.c const.h counter.h datetime.c datetime.h \
dmemory.h ecacore.c ecacore.h ecautil.c ecautil.h error.h \
etopo.h temp.h mask.h exception.c expr.c expr.h expr_lex.c \
expr_yacc.c expr_yacc.h features.c field.c field.h field2.c \
fieldc.c fieldmem.c fieldmer.c fieldzon.c functs.h \
gradsdeslib.c gradsdeslib.h grid.c grid.h grid_area.c \
cdo_getopt.c cdo_getopt.h cdo_task.c cdo_task.h cdo_history.c \
after_sptrans.c after_fctrans.c after_dvtrans.c \
after_vertint.c after_vertint.h after_namelist.c \
afterburnerlib.c afterburner.h vct_l191.h constants.h \
constants.c color.c color.h commandline.c const.h counter.h \
datetime.c datetime.h dmemory.h ecacore.c ecacore.h ecautil.c \
ecautil.h error.h etopo.h temp.h mask.h exception.c expr.c \
expr.h expr_lex.c expr_yacc.c expr_yacc.h features.c field.c \
field.h field2.c fieldc.c fieldmem.c fieldmer.c fieldzon.c \
functs.h gradsdeslib.c gradsdeslib.h grid.c grid.h grid_area.c \
grid_gme.c grid_lcc.c grid_rot.c gridreference.c griddes.c \
griddes.h griddes_h5.c griddes_nc.c hetaeta.c hetaeta.h \
institution.c interpol.c interpol.h job.c juldate.c \
......@@ -1020,6 +1021,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-cdo_getopt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-cdo_history.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-cdo_pthread.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-cdo_task.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-cdo_vlist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-color.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-commandline.Plo@am__quote@
......@@ -1147,6 +1149,13 @@ libcdo_la-cdo_getopt.lo: cdo_getopt.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-cdo_getopt.lo `test -f 'cdo_getopt.c' || echo '$(srcdir)/'`cdo_getopt.c
libcdo_la-cdo_task.lo: cdo_task.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-cdo_task.lo -MD -MP -MF $(DEPDIR)/libcdo_la-cdo_task.Tpo -c -o libcdo_la-cdo_task.lo `test -f 'cdo_task.c' || echo '$(srcdir)/'`cdo_task.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-cdo_task.Tpo $(DEPDIR)/libcdo_la-cdo_task.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdo_task.c' object='libcdo_la-cdo_task.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-cdo_task.lo `test -f 'cdo_task.c' || echo '$(srcdir)/'`cdo_task.c
libcdo_la-cdo_history.lo: cdo_history.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-cdo_history.lo -MD -MP -MF $(DEPDIR)/libcdo_la-cdo_history.Tpo -c -o libcdo_la-cdo_history.lo `test -f 'cdo_history.c' || echo '$(srcdir)/'`cdo_history.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-cdo_history.Tpo $(DEPDIR)/libcdo_la-cdo_history.Plo
......
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#if defined(HAVE_LIBPTHREAD)
#include <pthread.h>
#endif
#include "cdo_task.h"
enum cdo_pt_state {
SETUP,
IDLE,
JOB,
DIE
};
typedef struct cdo_task_info {
void *(*routine)(void *);
void *arg;
void *result;
enum cdo_pt_state state;
#if defined(HAVE_LIBPTHREAD)
pthread_t thread;
pthread_cond_t work_cond;
pthread_mutex_t work_mtx;
pthread_cond_t boss_cond;
pthread_mutex_t boss_mtx;
#endif
} cdo_task_t;
#if defined(HAVE_LIBPTHREAD)
static
void *cdo_task(void *task)
{
cdo_task_t *task_info = (cdo_task_t *) task;
// cond_wait mutex must be locked before we can wait
pthread_mutex_lock(&(task_info->work_mtx));
printf("<worker> start\n");
// ensure boss is waiting
pthread_mutex_lock(&(task_info->boss_mtx));
// signal to boss that setup is complete
task_info->state = IDLE;
// wake-up signal
pthread_cond_signal(&(task_info->boss_cond));
pthread_mutex_unlock(&(task_info->boss_mtx));
while ( 1 )
{
pthread_cond_wait(&(task_info->work_cond), &(task_info->work_mtx));
if ( DIE == task_info->state )
{
// kill thread
break;
}
if ( IDLE == task_info->state )
{
// accidental wake-up
continue;
}
// do blocking task
printf("<worker> JOB start\n");
task_info->routine(task_info->arg);
printf("<worker> JOB end\n");
// ensure boss is waiting
pthread_mutex_lock(&(task_info->boss_mtx));
// indicate that job is done
task_info->state = IDLE;
// wake-up signal
pthread_cond_signal(&(task_info->boss_cond));
pthread_mutex_unlock(&(task_info->boss_mtx));
}
pthread_mutex_unlock(&(task_info->work_mtx));
pthread_exit(NULL);
}
#endif
void cdo_task_start(void *task, void *(*task_routine)(void *), void *task_arg)
{
if ( !task ) return;
cdo_task_t *task_info = (cdo_task_t *) task;
// ensure worker is waiting
#if defined(HAVE_LIBPTHREAD)
pthread_mutex_lock(&(task_info->work_mtx));
#endif
// set job information & state
task_info->routine = task_routine;
task_info->arg = task_arg;
task_info->state = JOB;
// wake-up signal
#if defined(HAVE_LIBPTHREAD)
pthread_cond_signal(&(task_info->work_cond));
pthread_mutex_unlock(&(task_info->work_mtx));
#endif
}
void *cdo_task_wait(void *task)
{
if ( !task ) return NULL;
cdo_task_t *task_info = (cdo_task_t *) task;
#if defined(HAVE_LIBPTHREAD)
while (1)
{
pthread_cond_wait(&(task_info->boss_cond), &(task_info->boss_mtx));
if ( IDLE == task_info->state ) break;
}
#endif
return task_info->result;
}
void *cdo_task_new()
{
cdo_task_t *task_info = NULL;
#if defined(HAVE_LIBPTHREAD)
task_info = (cdo_task_t *) malloc(sizeof(cdo_task_t));
task_info->routine = NULL;
task_info->arg = NULL;
task_info->result = NULL;
task_info->state = SETUP;
pthread_cond_init(&(task_info->work_cond), NULL);
pthread_mutex_init(&(task_info->work_mtx), NULL);
pthread_cond_init(&(task_info->boss_cond), NULL);
pthread_mutex_init(&(task_info->boss_mtx), NULL);
pthread_mutex_lock(&(task_info->boss_mtx));
pthread_create(&(task_info->thread), NULL, cdo_task, (void *)task_info);
cdo_task_wait(task_info);
#endif
return (void *)task_info;
}
void cdo_task_delete(void *task)
{
cdo_task_t *task_info = (cdo_task_t *) task;
#if defined(HAVE_LIBPTHREAD)
// ensure the worker is waiting
pthread_mutex_lock(&(task_info->work_mtx));
printf("cdo_task_delete: send DIE to <worker>\n");
task_info->state = DIE;
// wake-up signal
pthread_cond_signal(&(task_info->work_cond));
pthread_mutex_unlock(&(task_info->work_mtx));
// wait for thread to exit
pthread_join(task_info->thread, NULL);
pthread_mutex_destroy(&(task_info->work_mtx));
pthread_cond_destroy(&(task_info->work_cond));
pthread_mutex_unlock(&(task_info->boss_mtx));
pthread_mutex_destroy(&(task_info->boss_mtx));
pthread_cond_destroy(&(task_info->boss_cond));
#endif
if ( task_info ) free(task_info);
}
#ifdef TEST_CDO_TASK
void *mytask(void *arg)
{
printf("run mytask\n");
}
int main(int argc, char **argv)
{
void *task = cdo_task_new();
printf("Init done\n");
void *myarg;
void *myresult;
cdo_task_start(task, mytask, myarg);
myresult = cdo_task_wait(task);
cdo_task_start(task, mytask, myarg);
myresult = cdo_task_wait(task);
cdo_task_delete(task);
return 0;
}
#endif
#ifndef _CDO_TASK_H
#define _CDO_TASK_H
void cdo_task_start(void *task, void *(*task_routine)(void *), void *task_arg);
void *cdo_task_wait(void *task);
void *cdo_task_new();
void cdo_task_delete(void *task);
#endif /* _CDO_TASK_H */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment