Skip to content

Commit ea5f75a

Browse files
committed
Merge branch 'np/malloc-threading'
* np/malloc-threading: Thread-safe xmalloc and xrealloc needs a recursive mutex Make xmalloc and xrealloc thread-safe
2 parents af65543 + 9374919 commit ea5f75a

File tree

7 files changed

+54
-8
lines changed

7 files changed

+54
-8
lines changed

builtin/grep.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
#include "dir.h"
1818

1919
#ifndef NO_PTHREADS
20-
#include "thread-utils.h"
2120
#include <pthread.h>
21+
#include "thread-utils.h"
2222
#endif
2323

2424
static char const * const grep_usage[] = {

builtin/pack-objects.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
#include "refs.h"
1919

2020
#ifndef NO_PTHREADS
21-
#include "thread-utils.h"
2221
#include <pthread.h>
22+
#include "thread-utils.h"
2323
#endif
2424

2525
static const char pack_usage[] =
@@ -1522,6 +1522,13 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
15221522

15231523
#ifndef NO_PTHREADS
15241524

1525+
static void try_to_free_from_threads(size_t size)
1526+
{
1527+
read_lock();
1528+
release_pack_memory(size, -1);
1529+
read_unlock();
1530+
}
1531+
15251532
/*
15261533
* The main thread waits on the condition that (at least) one of the workers
15271534
* has stopped working (which is indicated in the .working member of
@@ -1552,14 +1559,16 @@ static pthread_cond_t progress_cond;
15521559
*/
15531560
static void init_threaded_search(void)
15541561
{
1555-
pthread_mutex_init(&read_mutex, NULL);
1562+
init_recursive_mutex(&read_mutex);
15561563
pthread_mutex_init(&cache_mutex, NULL);
15571564
pthread_mutex_init(&progress_mutex, NULL);
15581565
pthread_cond_init(&progress_cond, NULL);
1566+
set_try_to_free_routine(try_to_free_from_threads);
15591567
}
15601568

15611569
static void cleanup_threaded_search(void)
15621570
{
1571+
set_try_to_free_routine(NULL);
15631572
pthread_cond_destroy(&progress_cond);
15641573
pthread_mutex_destroy(&read_mutex);
15651574
pthread_mutex_destroy(&cache_mutex);

compat/win32/pthread.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@
1818
*/
1919
#define pthread_mutex_t CRITICAL_SECTION
2020

21-
#define pthread_mutex_init(a,b) InitializeCriticalSection((a))
21+
#define pthread_mutex_init(a,b) (InitializeCriticalSection((a)), 0)
2222
#define pthread_mutex_destroy(a) DeleteCriticalSection((a))
2323
#define pthread_mutex_lock EnterCriticalSection
2424
#define pthread_mutex_unlock LeaveCriticalSection
2525

26+
typedef int pthread_mutexattr_t;
27+
#define pthread_mutexattr_init(a) (*(a) = 0)
28+
#define pthread_mutexattr_destroy(a) do {} while (0)
29+
#define pthread_mutexattr_settype(a, t) 0
30+
#define PTHREAD_MUTEX_RECURSIVE 0
31+
2632
/*
2733
* Implement simple condition variable for Windows threads, based on ACE
2834
* implementation.

git-compat-util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,8 @@ static inline void *gitmempcpy(void *dest, const void *src, size_t n)
356356

357357
extern void release_pack_memory(size_t, int);
358358

359+
extern void set_try_to_free_routine(void (*routine)(size_t));
360+
359361
extern char *xstrdup(const char *str);
360362
extern void *xmalloc(size_t size);
361363
extern void *xmallocz(size_t size);

thread-utils.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "cache.h"
2+
#include <pthread.h>
23

34
#if defined(hpux) || defined(__hpux) || defined(_hpux)
45
# include <sys/pstat.h>
@@ -43,3 +44,18 @@ int online_cpus(void)
4344

4445
return 1;
4546
}
47+
48+
int init_recursive_mutex(pthread_mutex_t *m)
49+
{
50+
pthread_mutexattr_t a;
51+
int ret;
52+
53+
ret = pthread_mutexattr_init(&a);
54+
if (!ret) {
55+
ret = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE);
56+
if (!ret)
57+
ret = pthread_mutex_init(m, &a);
58+
pthread_mutexattr_destroy(&a);
59+
}
60+
return ret;
61+
}

thread-utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
#define THREAD_COMPAT_H
33

44
extern int online_cpus(void);
5+
extern int init_recursive_mutex(pthread_mutex_t*);
56

67
#endif /* THREAD_COMPAT_H */

wrapper.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,23 @@
33
*/
44
#include "cache.h"
55

6+
static void try_to_free_builtin(size_t size)
7+
{
8+
release_pack_memory(size, -1);
9+
}
10+
11+
static void (*try_to_free_routine)(size_t size) = try_to_free_builtin;
12+
13+
void set_try_to_free_routine(void (*routine)(size_t))
14+
{
15+
try_to_free_routine = (routine) ? routine : try_to_free_builtin;
16+
}
17+
618
char *xstrdup(const char *str)
719
{
820
char *ret = strdup(str);
921
if (!ret) {
10-
release_pack_memory(strlen(str) + 1, -1);
22+
try_to_free_routine(strlen(str) + 1);
1123
ret = strdup(str);
1224
if (!ret)
1325
die("Out of memory, strdup failed");
@@ -21,7 +33,7 @@ void *xmalloc(size_t size)
2133
if (!ret && !size)
2234
ret = malloc(1);
2335
if (!ret) {
24-
release_pack_memory(size, -1);
36+
try_to_free_routine(size);
2537
ret = malloc(size);
2638
if (!ret && !size)
2739
ret = malloc(1);
@@ -67,7 +79,7 @@ void *xrealloc(void *ptr, size_t size)
6779
if (!ret && !size)
6880
ret = realloc(ptr, 1);
6981
if (!ret) {
70-
release_pack_memory(size, -1);
82+
try_to_free_routine(size);
7183
ret = realloc(ptr, size);
7284
if (!ret && !size)
7385
ret = realloc(ptr, 1);
@@ -83,7 +95,7 @@ void *xcalloc(size_t nmemb, size_t size)
8395
if (!ret && (!nmemb || !size))
8496
ret = calloc(1, 1);
8597
if (!ret) {
86-
release_pack_memory(nmemb * size, -1);
98+
try_to_free_routine(nmemb * size);
8799
ret = calloc(nmemb, size);
88100
if (!ret && (!nmemb || !size))
89101
ret = calloc(1, 1);

0 commit comments

Comments
 (0)