summaryrefslogtreecommitdiff
path: root/src/thread-utils.h
blob: 0029e4bc1110d05e9592b5aa9be56cba288cfaa4 (plain)
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
#ifndef INCLUDE_thread_utils_h__
#define INCLUDE_thread_utils_h__

#if defined(GIT_HAS_PTHREAD)
	typedef pthread_t git_thread;
#	define git_thread_create(thread, attr, start_routine, arg) pthread_create(thread, attr, start_routine, arg)
#	define git_thread_kill(thread) pthread_cancel(thread)
#	define git_thread_exit(status)	pthread_exit(status)
#	define git_thread_join(id, status) pthread_join(id, status)

	/* Pthreads Mutex */
	typedef pthread_mutex_t git_lck;
#	define GITLCK_INIT      PTHREAD_MUTEX_INITIALIZER
#	define gitlck_init(a)   pthread_mutex_init(a, NULL)
#	define gitlck_lock(a)   pthread_mutex_lock(a)
#	define gitlck_unlock(a) pthread_mutex_unlock(a)
#	define gitlck_free(a)   pthread_mutex_destroy(a)

	/* Pthreads condition vars */
	typedef pthread_cond_t git_cnd;
#	define GITCND_INIT			PTHREAD_COND_INITIALIZER
#	define gitcnd_init(c, a)	pthread_cond_init(c, a)
#	define gitcnd_free(c)		pthread_cond_destroy(c)
#	define gitcnd_wait(c, l)	pthread_cond_wait(c, l)
#	define gitcnd_signal(c)		pthread_cond_signal(c)
#	define gitcnd_broadcast(c)	pthread_cond_broadcast(c)

#	if defined(GIT_HAS_ASM_ATOMIC)
#		include <asm/atomic.h>
		typedef atomic_t git_refcnt;
#		define gitrc_init(a, v) atomic_set(a, v)
#		define gitrc_inc(a)		atomic_inc_return(a)
#		define gitrc_dec(a)		atomic_dec_and_test(a)
#		define gitrc_free(a)	(void)0
#	elif defined(GIT_WIN32)
		typedef long git_refcnt;
#		define gitrc_init(a, v)	(*a = v)
#		define gitrc_inc(a)		(InterlockedIncrement(a))
#		define gitrc_dec(a)		(!InterlockedDecrement(a))
#		define gitrc_free(a)	(void)0
#	else
		typedef struct { git_lck lock; int counter; } git_refcnt;

		/** Initialize to 0.  No memory barrier is issued. */
		GIT_INLINE(void) gitrc_init(git_refcnt *p, int value)
		{
			gitlck_init(&p->lock);
			p->counter = value;
		}

		/**
		 * Increment.
		 *
		 * Atomically increments @p by 1.  A memory barrier is also
		 * issued before and after the operation.
		 *
		 * @param p pointer of type git_refcnt
		 */
		GIT_INLINE(void) gitrc_inc(git_refcnt *p)
		{
			gitlck_lock(&p->lock);
			p->counter++;
			gitlck_unlock(&p->lock);
		}

		/**
		 * Decrement and test.
		 *
		 * Atomically decrements @p by 1 and returns true if the
		 * result is 0, or false for all other cases.  A memory
		 * barrier is also issued before and after the operation.
		 *
		 * @param p pointer of type git_refcnt
		 */
		GIT_INLINE(int) gitrc_dec(git_refcnt *p)
		{
			int c;
			gitlck_lock(&p->lock);
			c = --p->counter;
			gitlck_unlock(&p->lock);
			return !c;
		}

		/** Free any resources associated with the counter. */
#		define gitrc_free(p) gitlck_free(&(p)->lock)
#	endif

#elif defined(GIT_THREADS)
#	error GIT_THREADS but no git_lck implementation

#else
	/* no threads support */
	typedef struct { int dummy; } git_lck;
#	define GIT_MUTEX_INIT   {}
#	define gitlck_init(a)   (void)0
#	define gitlck_lock(a)   (void)0
#	define gitlck_unlock(a) (void)0
#	define gitlck_free(a)   (void)0

	typedef struct { int counter; } git_refcnt;
#	define gitrc_init(a,v) ((a)->counter = v)
#	define gitrc_inc(a)    ((a)->counter++)
#	define gitrc_dec(a)    (--(a)->counter == 0)
#	define gitrc_free(a)   (void)0
#endif

extern int git_online_cpus(void);

#endif /* INCLUDE_thread_utils_h__ */