From edf2ad46f4c0f403b90d3058018a295baa9d0753 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Jun 2015 13:46:01 +0200 Subject: Replace semaphore with a mutex A mutex (in a shared memory segment) is the correct synchronisation primitive here. I had confused myself... --- libcrystfel/src/integration.c | 32 +++++++++++++++++--------------- libcrystfel/src/integration.h | 4 +--- src/im-sandbox.c | 35 ++++++++++++++++++++++++----------- src/process_image.c | 4 ++-- src/process_image.h | 2 +- 5 files changed, 45 insertions(+), 32 deletions(-) diff --git a/libcrystfel/src/integration.c b/libcrystfel/src/integration.c index 336e99ed..16c27bbe 100644 --- a/libcrystfel/src/integration.c +++ b/libcrystfel/src/integration.c @@ -38,7 +38,6 @@ #include #include #include -#include #ifdef HAVE_CURSES_COLOR #include @@ -253,14 +252,14 @@ static void show_reference_profile(struct intcontext *ic, int i) static void show_peak_box(struct intcontext *ic, struct peak_box *bx, - sem_t *term_sem) + pthread_mutex_t *term_lock) { #ifdef HAVE_CURSES_COLOR int q; signed int h, k, l; double fs, ss; - if ( term_sem != NULL ) sem_wait(term_sem); + if ( term_lock != NULL ) pthread_mutex_lock(term_lock); initscr(); clear(); @@ -324,7 +323,7 @@ static void show_peak_box(struct intcontext *ic, struct peak_box *bx, getch(); endwin(); - if ( term_sem != NULL ) sem_post(term_sem); + if ( term_lock != NULL ) pthread_mutex_unlock(term_lock); #else STATUS("Not showing peak box because CrystFEL was compiled without " "ncurses.\n"); @@ -1171,7 +1170,7 @@ static int get_int_diag(struct intcontext *ic, Reflection *refl) static void integrate_prof2d_once(struct intcontext *ic, struct peak_box *bx, - sem_t *sem) + pthread_mutex_t *term_lock) { bx->intensity = fit_intensity(ic, bx); bx->sigma = calc_sigma(ic, bx); @@ -1201,7 +1200,9 @@ static void integrate_prof2d_once(struct intcontext *ic, struct peak_box *bx, set_redundancy(bx->refl, 0); } - if ( get_int_diag(ic, bx->refl) ) show_peak_box(ic, bx, sem); + if ( get_int_diag(ic, bx->refl) ) { + show_peak_box(ic, bx, term_lock); + } } else { @@ -1294,7 +1295,7 @@ static void integrate_prof2d(IntegrationMethod meth, Crystal *cr, struct image *image, IntDiag int_diag, signed int idh, signed int idk, signed int idl, double ir_inn, double ir_mid, double ir_out, - sem_t *term_sem, int **masks) + pthread_mutex_t *term_lock, int **masks) { RefList *list; UnitCell *cell; @@ -1338,7 +1339,7 @@ static void integrate_prof2d(IntegrationMethod meth, for ( i=0; ioffs_ss; set_detector_pos(refl, pfs, pss); - if ( get_int_diag(ic, refl) ) show_peak_box(ic, bx, term_sem); + if ( get_int_diag(ic, refl) ) show_peak_box(ic, bx, term_lock); if ( intensity < -5.0*sigma ) { ic->n_implausible++; @@ -1550,7 +1551,7 @@ static void integrate_rings(IntegrationMethod meth, Crystal *cr, struct image *image, IntDiag int_diag, signed int idh, signed int idk, signed int idl, double ir_inn, double ir_mid, double ir_out, - sem_t *term_sem, int **masks) + pthread_mutex_t *term_lock, int **masks) { RefList *list; Reflection *refl; @@ -1586,7 +1587,7 @@ static void integrate_rings(IntegrationMethod meth, refl != NULL; refl = next_refl(refl, iter) ) { - integrate_rings_once(refl, image, &ic, cell, term_sem); + integrate_rings_once(refl, image, &ic, cell, term_lock); } //refine_rigid_groups(&ic); @@ -1602,7 +1603,8 @@ void integrate_all_4(struct image *image, IntegrationMethod meth, PartialityModel pmodel, double push_res, double ir_inn, double ir_mid, double ir_out, IntDiag int_diag, - signed int idh, signed int idk, signed int idl, sem_t *sem) + signed int idh, signed int idk, signed int idl, + pthread_mutex_t *term_lock) { int i; int *masks[image->det->n_panels]; @@ -1642,14 +1644,14 @@ void integrate_all_4(struct image *image, IntegrationMethod meth, integrate_rings(meth, cr, image, int_diag, idh, idk, idl, ir_inn, ir_mid, ir_out, - sem, masks); + term_lock, masks); break; case INTEGRATION_PROF2D : integrate_prof2d(meth, cr, image, int_diag, idh, idk, idl, ir_inn, ir_mid, ir_out, - sem, masks); + term_lock, masks); break; default : diff --git a/libcrystfel/src/integration.h b/libcrystfel/src/integration.h index 7414f818..a012fc14 100644 --- a/libcrystfel/src/integration.h +++ b/libcrystfel/src/integration.h @@ -33,8 +33,6 @@ #include #endif -#include - #include "geometry.h" /** @@ -128,7 +126,7 @@ extern void integrate_all_4(struct image *image, IntegrationMethod meth, double ir_inn, double ir_mid, double ir_out, IntDiag int_diag, signed int idh, signed int idk, signed int idl, - sem_t *term_sem); + pthread_mutex_t *term_lock); #ifdef __cplusplus diff --git a/src/im-sandbox.c b/src/im-sandbox.c index b800f5b4..df50199c 100644 --- a/src/im-sandbox.c +++ b/src/im-sandbox.c @@ -3,13 +3,13 @@ * * Sandbox for indexing * - * Copyright © 2012-2014 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2012-2015 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * Copyright © 2012 Richard Kirian * Copyright © 2012 Lorenzo Galli * * Authors: - * 2010-2014 Thomas White + * 2010-2015 Thomas White * 2014 Valerio Mariani * 2011 Richard Kirian * 2012 Lorenzo Galli @@ -49,7 +49,6 @@ #include #include #include -#include #ifdef HAVE_CLOCK_GETTIME #include @@ -89,7 +88,7 @@ struct sb_reader struct sb_shm { - sem_t term_sem; + pthread_mutex_t term_lock; }; @@ -368,7 +367,7 @@ static int read_fpe_data(struct buffer_data *bd) static void run_work(const struct index_args *iargs, int filename_pipe, int results_pipe, Stream *st, - int cookie, const char *tmpdir, sem_t *term_sem) + int cookie, const char *tmpdir, pthread_mutex_t *term_lock) { FILE *fh; int allDone = 0; @@ -503,7 +502,7 @@ static void run_work(const struct index_args *iargs, pargs.n_crystals = 0; process_image(iargs, &pargs, st, cookie, tmpdir, - results_pipe, ser, term_sem); + results_pipe, ser, term_lock); /* Request another image */ c = sprintf(buf, "%i\n", pargs.n_crystals); @@ -824,7 +823,7 @@ static void start_worker_process(struct sandbox *sb, int slot) st = open_stream_fd_for_write(stream_pipe[1]); run_work(sb->iargs, filename_pipe[0], result_pipe[1], - st, slot, tmp, &sb->shared->term_sem); + st, slot, tmp, &sb->shared->term_lock); close_stream(st); //close(filename_pipe[0]); @@ -906,6 +905,8 @@ static void handle_zombie(struct sandbox *sb) static int setup_shm(struct sandbox *sb) { + pthread_mutexattr_t attr; + sb->shared = mmap(NULL, sizeof(struct sb_shm), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); @@ -914,11 +915,23 @@ static int setup_shm(struct sandbox *sb) return 1; } - if ( sem_init(&sb->shared->term_sem, 1, 1) ) { - ERROR("Terminal semaphore setup failed: %s\n", strerror(errno)); + if ( pthread_mutexattr_init(&attr) ) { + ERROR("Failed to initialise mutex attr.\n"); + return 1; + } + + if ( pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) ) { + ERROR("Failed to set process shared attribute.\n"); return 1; } + if ( pthread_mutex_init(&sb->shared->term_lock, &attr) ) { + ERROR("Terminal lock setup failed.\n"); + return 1; + } + + pthread_mutexattr_destroy(&attr); + return 0; } @@ -1230,7 +1243,7 @@ void create_sandbox(struct index_args *iargs, int n_proc, char *prefix, /* Update progress */ lock_sandbox(sb); tNow = get_monotonic_seconds(); - r = sem_trywait(&sb->shared->term_sem); + r = pthread_mutex_trylock(&sb->shared->term_lock); if ((r==0) && (tNow >= sb->t_last_stats+STATS_EVERY_N_SECONDS)) { @@ -1250,7 +1263,7 @@ void create_sandbox(struct index_args *iargs, int n_proc, char *prefix, } - if ( r == 0 ) sem_post(&sb->shared->term_sem); + if ( r == 0 ) pthread_mutex_unlock(&sb->shared->term_lock); unlock_sandbox(sb); allDone = 1; diff --git a/src/process_image.c b/src/process_image.c index 5ead2c61..783ca464 100644 --- a/src/process_image.c +++ b/src/process_image.c @@ -78,7 +78,7 @@ static void try_refine_autoR(struct image *image, Crystal *cr) void process_image(const struct index_args *iargs, struct pattern_args *pargs, Stream *st, int cookie, const char *tmpdir, int results_pipe, - int serial, sem_t *term_sem) + int serial, pthread_mutex_t *term_lock) { float *data_for_measurement; size_t data_size; @@ -260,7 +260,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, iargs->ir_inn, iargs->ir_mid, iargs->ir_out, iargs->int_diag, iargs->int_diag_h, iargs->int_diag_k, iargs->int_diag_l, - term_sem); + term_lock); ret = write_chunk(st, &image, hdfile, iargs->stream_peaks, iargs->stream_refls, diff --git a/src/process_image.h b/src/process_image.h index 6e44c173..d982c4f0 100644 --- a/src/process_image.h +++ b/src/process_image.h @@ -104,7 +104,7 @@ struct pattern_args extern void process_image(const struct index_args *iargs, struct pattern_args *pargs, Stream *st, int cookie, const char *tmpdir, int results_pipe, - int serial, sem_t *term_sem); + int serial, pthread_mutex_t *term_lock); #endif /* PROCESS_IMAGEs_H */ -- cgit v1.2.3