Skip to content

Commit 0ec7935

Browse files
pcloudsgitster
authored andcommitted
thread-utils: macros to unconditionally compile pthreads API
When built with NO_PTHREADS, the macros are used make the code build even though pthreads header and library may be missing. The code can still have different code paths for no threads support with HAVE_THREADS variable. There are of course impacts on no-pthreads builds: - data structure may get slightly bigger because all the mutexes and pthread_t are present (as an int) - code execution is not impacted much. Locking (in hot path) is no-op. Other wrapper function calls really should not matter much. - the binary size grows bigger because of threaded code. But at least on Linux this does not matter, if some code is not executed, it's not mapped in memory. This is a preparation step to remove "#ifdef NO_PTHREADS" in the code mostly because of maintainability. As Jeff put it > it's probably OK to stop thinking of it as "non-threaded platforms > are the default and must pay zero cost" and more as "threaded > platforms are the default, and non-threaded ones are OK to pay a > small cost as long as they still work". Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c670b1f commit 0ec7935

File tree

3 files changed

+94
-4
lines changed

3 files changed

+94
-4
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,7 @@ LIB_OBJS += sub-process.o
991991
LIB_OBJS += symlinks.o
992992
LIB_OBJS += tag.o
993993
LIB_OBJS += tempfile.o
994+
LIB_OBJS += thread-utils.o
994995
LIB_OBJS += tmp-objdir.o
995996
LIB_OBJS += trace.o
996997
LIB_OBJS += trailer.o
@@ -1674,7 +1675,6 @@ ifdef NO_PTHREADS
16741675
else
16751676
BASIC_CFLAGS += $(PTHREAD_CFLAGS)
16761677
EXTLIBS += $(PTHREAD_LIBS)
1677-
LIB_OBJS += thread-utils.o
16781678
endif
16791679

16801680
ifdef HAVE_PATHS_H

thread-utils.c

+48
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
int online_cpus(void)
2222
{
23+
#ifdef NO_PTHREADS
24+
return 1;
25+
#else
2326
#ifdef _SC_NPROCESSORS_ONLN
2427
long ncpus;
2528
#endif
@@ -59,10 +62,12 @@ int online_cpus(void)
5962
#endif
6063

6164
return 1;
65+
#endif
6266
}
6367

6468
int init_recursive_mutex(pthread_mutex_t *m)
6569
{
70+
#ifndef NO_PTHREADS
6671
pthread_mutexattr_t a;
6772
int ret;
6873

@@ -74,4 +79,47 @@ int init_recursive_mutex(pthread_mutex_t *m)
7479
pthread_mutexattr_destroy(&a);
7580
}
7681
return ret;
82+
#else
83+
return 0;
84+
#endif
85+
}
86+
87+
#ifdef NO_PTHREADS
88+
int dummy_pthread_create(pthread_t *pthread, const void *attr,
89+
void *(*fn)(void *), void *data)
90+
{
91+
/*
92+
* Do nothing.
93+
*
94+
* The main purpose of this function is to break compiler's
95+
* flow analysis and avoid -Wunused-variable false warnings.
96+
*/
97+
return ENOSYS;
98+
}
99+
100+
int dummy_pthread_init(void *data)
101+
{
102+
/*
103+
* Do nothing.
104+
*
105+
* The main purpose of this function is to break compiler's
106+
* flow analysis or it may realize that functions like
107+
* pthread_mutex_init() is no-op, which means the (static)
108+
* variable is not used/initialized at all and trigger
109+
* -Wunused-variable
110+
*/
111+
return ENOSYS;
77112
}
113+
114+
int dummy_pthread_join(pthread_t pthread, void **retval)
115+
{
116+
/*
117+
* Do nothing.
118+
*
119+
* The main purpose of this function is to break compiler's
120+
* flow analysis and avoid -Wunused-variable false warnings.
121+
*/
122+
return ENOSYS;
123+
}
124+
125+
#endif

thread-utils.h

+45-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,54 @@
44
#ifndef NO_PTHREADS
55
#include <pthread.h>
66

7-
extern int online_cpus(void);
8-
extern int init_recursive_mutex(pthread_mutex_t*);
7+
#define HAVE_THREADS 1
98

109
#else
1110

12-
#define online_cpus() 1
11+
#define HAVE_THREADS 0
12+
13+
/*
14+
* macros instead of typedefs because pthread definitions may have
15+
* been pulled in by some system dependencies even though the user
16+
* wants to disable pthread.
17+
*/
18+
#define pthread_t int
19+
#define pthread_mutex_t int
20+
#define pthread_cond_t int
21+
#define pthread_key_t int
22+
23+
#define pthread_mutex_init(mutex, attr) dummy_pthread_init(mutex)
24+
#define pthread_mutex_lock(mutex)
25+
#define pthread_mutex_unlock(mutex)
26+
#define pthread_mutex_destroy(mutex)
27+
28+
#define pthread_cond_init(cond, attr) dummy_pthread_init(cond)
29+
#define pthread_cond_wait(cond, mutex)
30+
#define pthread_cond_signal(cond)
31+
#define pthread_cond_broadcast(cond)
32+
#define pthread_cond_destroy(cond)
33+
34+
#define pthread_key_create(key, attr) dummy_pthread_init(key)
35+
#define pthread_key_delete(key)
36+
37+
#define pthread_create(thread, attr, fn, data) \
38+
dummy_pthread_create(thread, attr, fn, data)
39+
#define pthread_join(thread, retval) \
40+
dummy_pthread_join(thread, retval)
41+
42+
#define pthread_setspecific(key, data)
43+
#define pthread_getspecific(key) NULL
44+
45+
int dummy_pthread_create(pthread_t *pthread, const void *attr,
46+
void *(*fn)(void *), void *data);
47+
int dummy_pthread_join(pthread_t pthread, void **retval);
48+
49+
int dummy_pthread_init(void *);
1350

1451
#endif
52+
53+
int online_cpus(void);
54+
int init_recursive_mutex(pthread_mutex_t*);
55+
56+
1557
#endif /* THREAD_COMPAT_H */

0 commit comments

Comments
 (0)