mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-09 23:39:55 +00:00
REORG: thread: move the thread init/affinity/stop to thread.c
haproxy.c still has to deal with pthread-specific low-level stuff that is OS-dependent. We should not have to deal with this there, and we do not need to access pthread anywhere else. Let's move these 3 functions to thread.c and keep empty inline ones for when threads are disabled.
This commit is contained in:
parent
19b18ad552
commit
d10385ac4b
@ -151,6 +151,18 @@ static inline unsigned long thread_isolated()
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void setup_extra_threads(void *(*handler)(void *))
|
||||
{
|
||||
}
|
||||
|
||||
static inline void wait_for_threads_completion()
|
||||
{
|
||||
}
|
||||
|
||||
static inline void set_thread_cpu_affinity()
|
||||
{
|
||||
}
|
||||
|
||||
#else /* !USE_THREAD */
|
||||
|
||||
/********************** THREADS ENABLED ************************/
|
||||
@ -166,6 +178,9 @@ void ha_tkill(unsigned int thr, int sig);
|
||||
void ha_tkillall(int sig);
|
||||
void ha_spin_init(HA_SPINLOCK_T *l);
|
||||
void ha_rwlock_init(HA_RWLOCK_T *l);
|
||||
void setup_extra_threads(void *(*handler)(void *));
|
||||
void wait_for_threads_completion();
|
||||
void set_thread_cpu_affinity();
|
||||
|
||||
extern volatile unsigned long all_threads_mask;
|
||||
extern volatile unsigned long threads_harmless_mask;
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <time.h>
|
||||
#include <syslog.h>
|
||||
#include <grp.h>
|
||||
|
||||
#ifdef USE_CPU_AFFINITY
|
||||
#include <sched.h>
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
@ -57,12 +58,6 @@
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cpuset.h>
|
||||
#endif
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_types.h>
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -2611,41 +2606,6 @@ __attribute__((noreturn)) void deinit_and_exit(int status)
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/* Tries to set the current thread's CPU affinity according to the cpu_map */
|
||||
static void set_thread_cpu_affinity()
|
||||
{
|
||||
#if defined(USE_THREAD) && defined(USE_CPU_AFFINITY)
|
||||
/* no affinity setting for the master process */
|
||||
if (master)
|
||||
return;
|
||||
|
||||
/* Now the CPU affinity for all threads */
|
||||
if (ha_cpuset_count(&cpu_map.proc))
|
||||
ha_cpuset_and(&cpu_map.thread[tid], &cpu_map.proc);
|
||||
|
||||
if (ha_cpuset_count(&cpu_map.thread[tid])) {/* only do this if the thread has a THREAD map */
|
||||
# if defined(__APPLE__)
|
||||
/* Note: this API is limited to the first 32/64 CPUs */
|
||||
unsigned long set = cpu_map.thread[tid].cpuset;
|
||||
int j;
|
||||
|
||||
while ((j = ffsl(set)) > 0) {
|
||||
thread_affinity_policy_data_t cpu_set = { j - 1 };
|
||||
thread_port_t mthread;
|
||||
|
||||
mthread = pthread_mach_thread_np(ha_thread_info[tid].pthread);
|
||||
thread_policy_set(mthread, THREAD_AFFINITY_POLICY, (thread_policy_t)&cpu_set, 1);
|
||||
set &= ~(1UL << (j - 1));
|
||||
}
|
||||
# else
|
||||
struct hap_cpuset *set = &cpu_map.thread[tid];
|
||||
|
||||
pthread_setaffinity_np(ha_thread_info[tid].pthread, sizeof(set->cpuset), &set->cpuset);
|
||||
# endif
|
||||
}
|
||||
#endif /* USE_THREAD && USE_CPU_AFFINITY */
|
||||
}
|
||||
|
||||
/* Runs the polling loop */
|
||||
void run_poll_loop()
|
||||
{
|
||||
@ -2857,49 +2817,6 @@ static void *run_thread_poll_loop(void *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Sets up threads, signals and masks, and starts threads 2 and above.
|
||||
* Does nothing when threads are disabled.
|
||||
*/
|
||||
static void setup_extra_threads()
|
||||
{
|
||||
#ifdef USE_THREAD
|
||||
sigset_t blocked_sig, old_sig;
|
||||
int i;
|
||||
|
||||
/* ensure the signals will be blocked in every thread */
|
||||
sigfillset(&blocked_sig);
|
||||
sigdelset(&blocked_sig, SIGPROF);
|
||||
sigdelset(&blocked_sig, SIGBUS);
|
||||
sigdelset(&blocked_sig, SIGFPE);
|
||||
sigdelset(&blocked_sig, SIGILL);
|
||||
sigdelset(&blocked_sig, SIGSEGV);
|
||||
pthread_sigmask(SIG_SETMASK, &blocked_sig, &old_sig);
|
||||
|
||||
/* Create nbthread-1 thread. The first thread is the current process */
|
||||
ha_thread_info[0].pthread = pthread_self();
|
||||
for (i = 1; i < global.nbthread; i++)
|
||||
pthread_create(&ha_thread_info[i].pthread, NULL, &run_thread_poll_loop, (void *)(long)i);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* waits for all threads to terminate. Does nothing when threads are
|
||||
* disabled.
|
||||
*/
|
||||
static void wait_for_threads_completion()
|
||||
{
|
||||
#ifdef USE_THREAD
|
||||
int i;
|
||||
|
||||
/* Wait the end of other threads */
|
||||
for (i = 1; i < global.nbthread; i++)
|
||||
pthread_join(ha_thread_info[i].pthread, NULL);
|
||||
|
||||
# if defined(DEBUG_THREAD) || defined(DEBUG_FULL)
|
||||
show_lock_stats();
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* set uid/gid depending on global settings */
|
||||
static void set_identity(const char *program_name)
|
||||
{
|
||||
@ -3474,7 +3391,7 @@ int main(int argc, char **argv)
|
||||
reset_usermsgs_ctx();
|
||||
|
||||
/* start threads 2 and above */
|
||||
setup_extra_threads();
|
||||
setup_extra_threads(&run_thread_poll_loop);
|
||||
|
||||
/* when multithreading we need to let only the thread 0 handle the signals */
|
||||
haproxy_unblock_signals();
|
||||
|
93
src/thread.c
93
src/thread.c
@ -16,11 +16,20 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef USE_CPU_AFFINITY
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cpuset.h>
|
||||
# include <sched.h>
|
||||
# if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
# include <sys/param.h>
|
||||
# ifdef __FreeBSD__
|
||||
# include <sys/cpuset.h>
|
||||
# endif
|
||||
# include <pthread_np.h>
|
||||
# endif
|
||||
# ifdef __APPLE__
|
||||
# include <mach/mach_types.h>
|
||||
# include <mach/thread_act.h>
|
||||
# include <mach/thread_policy.h>
|
||||
# endif
|
||||
# include <haproxy/cpuset.h>
|
||||
#endif
|
||||
|
||||
#include <haproxy/cfgparse.h>
|
||||
@ -171,6 +180,80 @@ void thread_sync_release()
|
||||
ha_thread_relax();
|
||||
}
|
||||
|
||||
/* Sets up threads, signals and masks, and starts threads 2 and above.
|
||||
* Does nothing when threads are disabled.
|
||||
*/
|
||||
void setup_extra_threads(void *(*handler)(void *))
|
||||
{
|
||||
sigset_t blocked_sig, old_sig;
|
||||
int i;
|
||||
|
||||
/* ensure the signals will be blocked in every thread */
|
||||
sigfillset(&blocked_sig);
|
||||
sigdelset(&blocked_sig, SIGPROF);
|
||||
sigdelset(&blocked_sig, SIGBUS);
|
||||
sigdelset(&blocked_sig, SIGFPE);
|
||||
sigdelset(&blocked_sig, SIGILL);
|
||||
sigdelset(&blocked_sig, SIGSEGV);
|
||||
pthread_sigmask(SIG_SETMASK, &blocked_sig, &old_sig);
|
||||
|
||||
/* Create nbthread-1 thread. The first thread is the current process */
|
||||
ha_thread_info[0].pthread = pthread_self();
|
||||
for (i = 1; i < global.nbthread; i++)
|
||||
pthread_create(&ha_thread_info[i].pthread, NULL, handler, (void *)(long)i);
|
||||
}
|
||||
|
||||
/* waits for all threads to terminate. Does nothing when threads are
|
||||
* disabled.
|
||||
*/
|
||||
void wait_for_threads_completion()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Wait the end of other threads */
|
||||
for (i = 1; i < global.nbthread; i++)
|
||||
pthread_join(ha_thread_info[i].pthread, NULL);
|
||||
|
||||
#if defined(DEBUG_THREAD) || defined(DEBUG_FULL)
|
||||
show_lock_stats();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Tries to set the current thread's CPU affinity according to the cpu_map */
|
||||
void set_thread_cpu_affinity()
|
||||
{
|
||||
#if defined(USE_CPU_AFFINITY)
|
||||
/* no affinity setting for the master process */
|
||||
if (master)
|
||||
return;
|
||||
|
||||
/* Now the CPU affinity for all threads */
|
||||
if (ha_cpuset_count(&cpu_map.proc))
|
||||
ha_cpuset_and(&cpu_map.thread[tid], &cpu_map.proc);
|
||||
|
||||
if (ha_cpuset_count(&cpu_map.thread[tid])) {/* only do this if the thread has a THREAD map */
|
||||
# if defined(__APPLE__)
|
||||
/* Note: this API is limited to the first 32/64 CPUs */
|
||||
unsigned long set = cpu_map.thread[tid].cpuset;
|
||||
int j;
|
||||
|
||||
while ((j = ffsl(set)) > 0) {
|
||||
thread_affinity_policy_data_t cpu_set = { j - 1 };
|
||||
thread_port_t mthread;
|
||||
|
||||
mthread = pthread_mach_thread_np(ha_thread_info[tid].pthread);
|
||||
thread_policy_set(mthread, THREAD_AFFINITY_POLICY, (thread_policy_t)&cpu_set, 1);
|
||||
set &= ~(1UL << (j - 1));
|
||||
}
|
||||
# else
|
||||
struct hap_cpuset *set = &cpu_map.thread[tid];
|
||||
|
||||
pthread_setaffinity_np(ha_thread_info[tid].pthread, sizeof(set->cpuset), &set->cpuset);
|
||||
# endif
|
||||
}
|
||||
#endif /* USE_CPU_AFFINITY */
|
||||
}
|
||||
|
||||
/* send signal <sig> to thread <thr> */
|
||||
void ha_tkill(unsigned int thr, int sig)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user