Merge branch 'np/malloc-threading'
* np/malloc-threading: Thread-safe xmalloc and xrealloc needs a recursive mutex Make xmalloc and xrealloc thread-safemaint
						commit
						ea5f75a64a
					
				|  | @ -17,8 +17,8 @@ | ||||||
| #include "dir.h" | #include "dir.h" | ||||||
|  |  | ||||||
| #ifndef NO_PTHREADS | #ifndef NO_PTHREADS | ||||||
| #include "thread-utils.h" |  | ||||||
| #include <pthread.h> | #include <pthread.h> | ||||||
|  | #include "thread-utils.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| static char const * const grep_usage[] = { | static char const * const grep_usage[] = { | ||||||
|  |  | ||||||
|  | @ -18,8 +18,8 @@ | ||||||
| #include "refs.h" | #include "refs.h" | ||||||
|  |  | ||||||
| #ifndef NO_PTHREADS | #ifndef NO_PTHREADS | ||||||
| #include "thread-utils.h" |  | ||||||
| #include <pthread.h> | #include <pthread.h> | ||||||
|  | #include "thread-utils.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| static const char pack_usage[] = | static const char pack_usage[] = | ||||||
|  | @ -1522,6 +1522,13 @@ static void find_deltas(struct object_entry **list, unsigned *list_size, | ||||||
|  |  | ||||||
| #ifndef NO_PTHREADS | #ifndef NO_PTHREADS | ||||||
|  |  | ||||||
|  | static void try_to_free_from_threads(size_t size) | ||||||
|  | { | ||||||
|  | 	read_lock(); | ||||||
|  | 	release_pack_memory(size, -1); | ||||||
|  | 	read_unlock(); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * The main thread waits on the condition that (at least) one of the workers |  * The main thread waits on the condition that (at least) one of the workers | ||||||
|  * has stopped working (which is indicated in the .working member of |  * has stopped working (which is indicated in the .working member of | ||||||
|  | @ -1552,14 +1559,16 @@ static pthread_cond_t progress_cond; | ||||||
|  */ |  */ | ||||||
| static void init_threaded_search(void) | static void init_threaded_search(void) | ||||||
| { | { | ||||||
| 	pthread_mutex_init(&read_mutex, NULL); | 	init_recursive_mutex(&read_mutex); | ||||||
| 	pthread_mutex_init(&cache_mutex, NULL); | 	pthread_mutex_init(&cache_mutex, NULL); | ||||||
| 	pthread_mutex_init(&progress_mutex, NULL); | 	pthread_mutex_init(&progress_mutex, NULL); | ||||||
| 	pthread_cond_init(&progress_cond, NULL); | 	pthread_cond_init(&progress_cond, NULL); | ||||||
|  | 	set_try_to_free_routine(try_to_free_from_threads); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void cleanup_threaded_search(void) | static void cleanup_threaded_search(void) | ||||||
| { | { | ||||||
|  | 	set_try_to_free_routine(NULL); | ||||||
| 	pthread_cond_destroy(&progress_cond); | 	pthread_cond_destroy(&progress_cond); | ||||||
| 	pthread_mutex_destroy(&read_mutex); | 	pthread_mutex_destroy(&read_mutex); | ||||||
| 	pthread_mutex_destroy(&cache_mutex); | 	pthread_mutex_destroy(&cache_mutex); | ||||||
|  |  | ||||||
|  | @ -18,11 +18,17 @@ | ||||||
|  */ |  */ | ||||||
| #define pthread_mutex_t CRITICAL_SECTION | #define pthread_mutex_t CRITICAL_SECTION | ||||||
|  |  | ||||||
| #define pthread_mutex_init(a,b) InitializeCriticalSection((a)) | #define pthread_mutex_init(a,b) (InitializeCriticalSection((a)), 0) | ||||||
| #define pthread_mutex_destroy(a) DeleteCriticalSection((a)) | #define pthread_mutex_destroy(a) DeleteCriticalSection((a)) | ||||||
| #define pthread_mutex_lock EnterCriticalSection | #define pthread_mutex_lock EnterCriticalSection | ||||||
| #define pthread_mutex_unlock LeaveCriticalSection | #define pthread_mutex_unlock LeaveCriticalSection | ||||||
|  |  | ||||||
|  | typedef int pthread_mutexattr_t; | ||||||
|  | #define pthread_mutexattr_init(a) (*(a) = 0) | ||||||
|  | #define pthread_mutexattr_destroy(a) do {} while (0) | ||||||
|  | #define pthread_mutexattr_settype(a, t) 0 | ||||||
|  | #define PTHREAD_MUTEX_RECURSIVE 0 | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Implement simple condition variable for Windows threads, based on ACE |  * Implement simple condition variable for Windows threads, based on ACE | ||||||
|  * implementation. |  * implementation. | ||||||
|  |  | ||||||
|  | @ -356,6 +356,8 @@ static inline void *gitmempcpy(void *dest, const void *src, size_t n) | ||||||
|  |  | ||||||
| extern void release_pack_memory(size_t, int); | extern void release_pack_memory(size_t, int); | ||||||
|  |  | ||||||
|  | extern void set_try_to_free_routine(void (*routine)(size_t)); | ||||||
|  |  | ||||||
| extern char *xstrdup(const char *str); | extern char *xstrdup(const char *str); | ||||||
| extern void *xmalloc(size_t size); | extern void *xmalloc(size_t size); | ||||||
| extern void *xmallocz(size_t size); | extern void *xmallocz(size_t size); | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #include "cache.h" | #include "cache.h" | ||||||
|  | #include <pthread.h> | ||||||
|  |  | ||||||
| #if defined(hpux) || defined(__hpux) || defined(_hpux) | #if defined(hpux) || defined(__hpux) || defined(_hpux) | ||||||
| #  include <sys/pstat.h> | #  include <sys/pstat.h> | ||||||
|  | @ -43,3 +44,18 @@ int online_cpus(void) | ||||||
|  |  | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int init_recursive_mutex(pthread_mutex_t *m) | ||||||
|  | { | ||||||
|  | 	pthread_mutexattr_t a; | ||||||
|  | 	int ret; | ||||||
|  |  | ||||||
|  | 	ret = pthread_mutexattr_init(&a); | ||||||
|  | 	if (!ret) { | ||||||
|  | 		ret = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE); | ||||||
|  | 		if (!ret) | ||||||
|  | 			ret = pthread_mutex_init(m, &a); | ||||||
|  | 		pthread_mutexattr_destroy(&a); | ||||||
|  | 	} | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -2,5 +2,6 @@ | ||||||
| #define THREAD_COMPAT_H | #define THREAD_COMPAT_H | ||||||
|  |  | ||||||
| extern int online_cpus(void); | extern int online_cpus(void); | ||||||
|  | extern int init_recursive_mutex(pthread_mutex_t*); | ||||||
|  |  | ||||||
| #endif /* THREAD_COMPAT_H */ | #endif /* THREAD_COMPAT_H */ | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								wrapper.c
								
								
								
								
							
							
						
						
									
										20
									
								
								wrapper.c
								
								
								
								
							|  | @ -3,11 +3,23 @@ | ||||||
|  */ |  */ | ||||||
| #include "cache.h" | #include "cache.h" | ||||||
|  |  | ||||||
|  | static void try_to_free_builtin(size_t size) | ||||||
|  | { | ||||||
|  | 	release_pack_memory(size, -1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void (*try_to_free_routine)(size_t size) = try_to_free_builtin; | ||||||
|  |  | ||||||
|  | void set_try_to_free_routine(void (*routine)(size_t)) | ||||||
|  | { | ||||||
|  | 	try_to_free_routine = (routine) ? routine : try_to_free_builtin; | ||||||
|  | } | ||||||
|  |  | ||||||
| char *xstrdup(const char *str) | char *xstrdup(const char *str) | ||||||
| { | { | ||||||
| 	char *ret = strdup(str); | 	char *ret = strdup(str); | ||||||
| 	if (!ret) { | 	if (!ret) { | ||||||
| 		release_pack_memory(strlen(str) + 1, -1); | 		try_to_free_routine(strlen(str) + 1); | ||||||
| 		ret = strdup(str); | 		ret = strdup(str); | ||||||
| 		if (!ret) | 		if (!ret) | ||||||
| 			die("Out of memory, strdup failed"); | 			die("Out of memory, strdup failed"); | ||||||
|  | @ -21,7 +33,7 @@ void *xmalloc(size_t size) | ||||||
| 	if (!ret && !size) | 	if (!ret && !size) | ||||||
| 		ret = malloc(1); | 		ret = malloc(1); | ||||||
| 	if (!ret) { | 	if (!ret) { | ||||||
| 		release_pack_memory(size, -1); | 		try_to_free_routine(size); | ||||||
| 		ret = malloc(size); | 		ret = malloc(size); | ||||||
| 		if (!ret && !size) | 		if (!ret && !size) | ||||||
| 			ret = malloc(1); | 			ret = malloc(1); | ||||||
|  | @ -67,7 +79,7 @@ void *xrealloc(void *ptr, size_t size) | ||||||
| 	if (!ret && !size) | 	if (!ret && !size) | ||||||
| 		ret = realloc(ptr, 1); | 		ret = realloc(ptr, 1); | ||||||
| 	if (!ret) { | 	if (!ret) { | ||||||
| 		release_pack_memory(size, -1); | 		try_to_free_routine(size); | ||||||
| 		ret = realloc(ptr, size); | 		ret = realloc(ptr, size); | ||||||
| 		if (!ret && !size) | 		if (!ret && !size) | ||||||
| 			ret = realloc(ptr, 1); | 			ret = realloc(ptr, 1); | ||||||
|  | @ -83,7 +95,7 @@ void *xcalloc(size_t nmemb, size_t size) | ||||||
| 	if (!ret && (!nmemb || !size)) | 	if (!ret && (!nmemb || !size)) | ||||||
| 		ret = calloc(1, 1); | 		ret = calloc(1, 1); | ||||||
| 	if (!ret) { | 	if (!ret) { | ||||||
| 		release_pack_memory(nmemb * size, -1); | 		try_to_free_routine(nmemb * size); | ||||||
| 		ret = calloc(nmemb, size); | 		ret = calloc(nmemb, size); | ||||||
| 		if (!ret && (!nmemb || !size)) | 		if (!ret && (!nmemb || !size)) | ||||||
| 			ret = calloc(1, 1); | 			ret = calloc(1, 1); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano