1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/*
* threads.h
*
* Definitions and shortcuts for POSIX threads.
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* This file part of: AstrOmatic software
*
* Copyright: (C) 2002-2020 IAP/CNRS/SorbonneU
*
* License: GNU General Public License
*
* AstrOmatic software is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
* AstrOmatic software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with AstrOmatic software.
* If not, see <http://www.gnu.org/licenses/>.
*
* Last modified: 26/08/2020
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef _THREADS_H_
#define _THREADS_H_
#include <pthread.h>
#include <signal.h>
/*---- Set defines according to machine's specificities and customizing -----*/
/*--------------------------- Technical constants ---------------------------*/
/*---------------------------- Synchro messages -----------------------------*/
#define STATE_FREE 0
#define STATE_READY 1
#define STATE_BUSY 2
/*------------------------------- Other Macros ------------------------------*/
#define QPTHREAD_ATTR_INIT(pthread_attr) \
{if (pthread_attr_init(pthread_attr)) \
error(EXIT_FAILURE, \
"*Error*: pthread_attr_init() failed for ", #pthread_attr );;}
#define QPTHREAD_ATTR_SETDETACHSTATE(pthread_attr, attr) \
{if (pthread_attr_setdetachstate(pthread_attr, attr)) \
error(EXIT_FAILURE, \
"*Error*: pthread_attr_setdetachstate() failed for ", \
#pthread_attr );;}
#define QPTHREAD_ATTR_DESTROY(pthread_attr) \
{if (pthread_attr_destroy(pthread_attr)) \
error(EXIT_FAILURE, \
"*Error*: pthread_attr_destroy() failed for ",#pthread_attr);;}
#define QPTHREAD_CREATE(pthread, attr, func, arg) \
{if (pthread_create(pthread, attr, func, arg)) \
error(EXIT_FAILURE, \
"*Error*: pthread_create() failed for ", #pthread );;}
#define QPTHREAD_CANCEL(pthread) \
{if (pthread_cancel(pthread)) \
warning( \
"failed to cancel ", #pthread );;}
#define QPTHREAD_JOIN(pthread, ret) \
{if (pthread_join(pthread, ret)) \
error(EXIT_FAILURE, \
"*Error*: pthread_join() failed for ", #pthread );;}
#define QPTHREAD_MUTEX_INIT(mutex, attr) \
{if (pthread_mutex_init(mutex, attr)) \
error(EXIT_FAILURE, \
"*Error*: pthread_mutex_init() failed for ", #mutex );;}
#define QPTHREAD_MUTEX_LOCK(mutex) \
{if (pthread_mutex_lock(mutex)) \
error(EXIT_FAILURE, \
"*Error*: pthread_mutex_lock() failed for ", #mutex );;}
#define QPTHREAD_MUTEX_UNLOCK(mutex) \
{if (pthread_mutex_unlock(mutex)) \
error(EXIT_FAILURE, \
"*Error*: pthread_mutex_unlock() failed for ", #mutex );;}
#define QPTHREAD_MUTEX_DESTROY(mutex) \
{if (pthread_mutex_destroy(mutex)) \
error(EXIT_FAILURE, \
"*Error*: pthread_mutex_destroy() failed for ", #mutex );;}
#define QPTHREAD_COND_INIT(cond, attr) \
{if (pthread_cond_init(cond, attr)) \
error(EXIT_FAILURE, \
"*Error*: pthread_cond_init() failed for ", #cond );;}
#define QPTHREAD_COND_WAIT(cond, mutex) \
{if (pthread_cond_wait(cond, mutex)) \
error(EXIT_FAILURE, \
"*Error*: pthread_cond_wait() failed for ", #cond );;}
#define QPTHREAD_COND_BROADCAST(cond) \
{if (pthread_cond_broadcast(cond)) \
error(EXIT_FAILURE, \
"*Error*: pthread_cond_broadcast() failed for ", #cond );;}
#define QPTHREAD_COND_SIGNAL(cond) \
{if (pthread_cond_signal(cond)) \
error(EXIT_FAILURE, \
"*Error*: pthread_cond_signal() failed for ", #cond );;}
#define QPTHREAD_COND_DESTROY(cond) \
{if (pthread_cond_destroy(cond)) \
error(EXIT_FAILURE, \
"*Error*: pthread_cond_destroy() failed for ", #cond );;}
/*------------------------------- Structures --------------------------------*/
typedef struct _threads_gate_t
{
int ngate; /* Gate counter */
int nthreads; /* Number of threads to manage */
void (*func)(void); /* Function to execute at wakeup */
pthread_mutex_t mutex; /* Main MutEx */
pthread_mutex_t block; /* Safety Mutex (avoid "rebound") */
pthread_cond_t condvar; /* Main condition variable */
pthread_cond_t last; /* To wake the remaining thread up */
} threads_gate_t;
/*----------------------------- Global variables ----------------------------*/
extern int nproc; /* Number of child threads */
/*--------------------------------- Functions -------------------------------*/
threads_gate_t *threads_gate_init(int nthreads, void (*func)(void));
extern void threads_gate_end(threads_gate_t *gate),
threads_gate_sync(threads_gate_t *gate);
#endif // _THREADS_H_
|