]> git.proxmox.com Git - libgit2.git/blob - src/thread-utils.h
Fix refcounting initialization
[libgit2.git] / src / thread-utils.h
1 #ifndef INCLUDE_thread_utils_h__
2 #define INCLUDE_thread_utils_h__
3
4 #if defined(GIT_HAS_PTHREAD)
5 typedef pthread_t git_thread;
6 # define git_thread_create(thread, attr, start_routine, arg) pthread_create(thread, attr, start_routine, arg)
7 # define git_thread_kill(thread) pthread_cancel(thread)
8 # define git_thread_exit(status) pthread_exit(status)
9 # define git_thread_join(id, status) pthread_join(id, status)
10
11 /* Pthreads Mutex */
12 typedef pthread_mutex_t git_lck;
13 # define GITLCK_INIT PTHREAD_MUTEX_INITIALIZER
14 # define gitlck_init(a) pthread_mutex_init(a, NULL)
15 # define gitlck_lock(a) pthread_mutex_lock(a)
16 # define gitlck_unlock(a) pthread_mutex_unlock(a)
17 # define gitlck_free(a) pthread_mutex_destroy(a)
18
19 /* Pthreads condition vars */
20 typedef pthread_cond_t git_cnd;
21 # define GITCND_INIT PTHREAD_COND_INITIALIZER
22 # define gitcnd_init(c, a) pthread_cond_init(c, a)
23 # define gitcnd_free(c) pthread_cond_destroy(c)
24 # define gitcnd_wait(c, l) pthread_cond_wait(c, l)
25 # define gitcnd_signal(c) pthread_cond_signal(c)
26 # define gitcnd_broadcast(c) pthread_cond_broadcast(c)
27
28 # if defined(GIT_HAS_ASM_ATOMIC)
29 # include <asm/atomic.h>
30 typedef atomic_t git_refcnt;
31 # define gitrc_init(a, v) atomic_set(a, v)
32 # define gitrc_inc(a) atomic_inc_return(a)
33 # define gitrc_dec(a) atomic_dec_and_test(a)
34 # define gitrc_free(a) (void)0
35 # elif defined(GIT_WIN32)
36 typedef long git_refcnt;
37 # define gitrc_init(a, v) (*a = v)
38 # define gitrc_inc(a) (InterlockedIncrement(a))
39 # define gitrc_dec(a) (!InterlockedDecrement(a))
40 # define gitrc_free(a) (void)0
41 # else
42 typedef struct { git_lck lock; int counter; } git_refcnt;
43
44 /** Initialize to 0. No memory barrier is issued. */
45 GIT_INLINE(void) gitrc_init(git_refcnt *p, int value)
46 {
47 gitlck_init(&p->lock);
48 p->counter = value;
49 }
50
51 /**
52 * Increment.
53 *
54 * Atomically increments @p by 1. A memory barrier is also
55 * issued before and after the operation.
56 *
57 * @param p pointer of type git_refcnt
58 */
59 GIT_INLINE(void) gitrc_inc(git_refcnt *p)
60 {
61 gitlck_lock(&p->lock);
62 p->counter++;
63 gitlck_unlock(&p->lock);
64 }
65
66 /**
67 * Decrement and test.
68 *
69 * Atomically decrements @p by 1 and returns true if the
70 * result is 0, or false for all other cases. A memory
71 * barrier is also issued before and after the operation.
72 *
73 * @param p pointer of type git_refcnt
74 */
75 GIT_INLINE(int) gitrc_dec(git_refcnt *p)
76 {
77 int c;
78 gitlck_lock(&p->lock);
79 c = --p->counter;
80 gitlck_unlock(&p->lock);
81 return !c;
82 }
83
84 /** Free any resources associated with the counter. */
85 # define gitrc_free(p) gitlck_free(&(p)->lock)
86 # endif
87
88 #elif defined(GIT_THREADS)
89 # error GIT_THREADS but no git_lck implementation
90
91 #else
92 /* no threads support */
93 typedef struct { int dummy; } git_lck;
94 # define GIT_MUTEX_INIT {}
95 # define gitlck_init(a) (void)0
96 # define gitlck_lock(a) (void)0
97 # define gitlck_unlock(a) (void)0
98 # define gitlck_free(a) (void)0
99
100 typedef struct { int counter; } git_refcnt;
101 # define gitrc_init(a,v) ((a)->counter = v)
102 # define gitrc_inc(a) ((a)->counter++)
103 # define gitrc_dec(a) (--(a)->counter == 0)
104 # define gitrc_free(a) (void)0
105 #endif
106
107 extern int git_online_cpus(void);
108
109 #endif /* INCLUDE_thread_utils_h__ */