]> git.proxmox.com Git - libgit2.git/blame - src/win32/pthread.c
Add git__compare_and_swap and use it
[libgit2.git] / src / win32 / pthread.c
CommitLineData
bbcc7ffc 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
bbcc7ffc 3 *
bb742ede
VM
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
bbcc7ffc
VM
6 */
7
8#include "pthread.h"
9
deafee7b
RB
10int pthread_create(
11 pthread_t *GIT_RESTRICT thread,
12 const pthread_attr_t *GIT_RESTRICT attr,
13 void *(*start_routine)(void*),
14 void *GIT_RESTRICT arg)
bbcc7ffc 15{
854eccbb 16 GIT_UNUSED(attr);
deafee7b
RB
17 *thread = (pthread_t) CreateThread(
18 NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, NULL);
19 return *thread ? 0 : -1;
bbcc7ffc
VM
20}
21
bbcc7ffc
VM
22int pthread_join(pthread_t thread, void **value_ptr)
23{
87d9869f
VM
24 int ret;
25 ret = WaitForSingleObject(thread, INFINITE);
26 if (ret && value_ptr)
27 GetExitCodeThread(thread, (void*) value_ptr);
28 return -(!!ret);
bbcc7ffc
VM
29}
30
bb3de0c4 31int pthread_mutex_init(pthread_mutex_t *GIT_RESTRICT mutex,
854eccbb 32 const pthread_mutexattr_t *GIT_RESTRICT mutexattr)
bbcc7ffc 33{
854eccbb 34 GIT_UNUSED(mutexattr);
87d9869f
VM
35 InitializeCriticalSection(mutex);
36 return 0;
bbcc7ffc
VM
37}
38
39int pthread_mutex_destroy(pthread_mutex_t *mutex)
40{
87d9869f
VM
41 DeleteCriticalSection(mutex);
42 return 0;
bbcc7ffc
VM
43}
44
bb3de0c4 45int pthread_mutex_lock(pthread_mutex_t *mutex)
bbcc7ffc 46{
87d9869f
VM
47 EnterCriticalSection(mutex);
48 return 0;
bbcc7ffc
VM
49}
50
bb3de0c4 51int pthread_mutex_unlock(pthread_mutex_t *mutex)
bbcc7ffc 52{
87d9869f
VM
53 LeaveCriticalSection(mutex);
54 return 0;
bbcc7ffc
VM
55}
56
5e4f2b5f
PK
57int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
58{
59 /* We don't support non-default attributes. */
60 if (attr)
61 return EINVAL;
62
63 /* This is an auto-reset event. */
64 *cond = CreateEventW(NULL, FALSE, FALSE, NULL);
65 assert(*cond);
66
67 /* If we can't create the event, claim that the reason was out-of-memory.
68 * The actual reason can be fetched with GetLastError(). */
69 return *cond ? 0 : ENOMEM;
70}
71
72int pthread_cond_destroy(pthread_cond_t *cond)
73{
74 BOOL closed;
75
76 if (!cond)
77 return EINVAL;
78
79 closed = CloseHandle(*cond);
80 assert(closed);
b4491b99 81 GIT_UNUSED(closed);
5e4f2b5f
PK
82
83 *cond = NULL;
84 return 0;
85}
86
87int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
88{
89 int error;
90 DWORD wait_result;
91
92 if (!cond || !mutex)
93 return EINVAL;
94
95 /* The caller must be holding the mutex. */
96 error = pthread_mutex_unlock(mutex);
97
98 if (error)
99 return error;
100
101 wait_result = WaitForSingleObject(*cond, INFINITE);
102 assert(WAIT_OBJECT_0 == wait_result);
b4491b99 103 GIT_UNUSED(wait_result);
5e4f2b5f
PK
104
105 return pthread_mutex_lock(mutex);
106}
107
108int pthread_cond_signal(pthread_cond_t *cond)
109{
110 BOOL signaled;
111
112 if (!cond)
113 return EINVAL;
114
115 signaled = SetEvent(*cond);
116 assert(signaled);
b4491b99 117 GIT_UNUSED(signaled);
5e4f2b5f
PK
118
119 return 0;
120}
121
122/* pthread_cond_broadcast is not implemented because doing so with just Win32 events
123 * is quite complicated, and no caller in libgit2 uses it yet. */
124
bbcc7ffc
VM
125int pthread_num_processors_np(void)
126{
87d9869f
VM
127 DWORD_PTR p, s;
128 int n = 0;
bbcc7ffc 129
87d9869f
VM
130 if (GetProcessAffinityMask(GetCurrentProcess(), &p, &s))
131 for (; p; p >>= 1)
132 n += p&1;
bbcc7ffc 133
87d9869f 134 return n ? n : 1;
bbcc7ffc
VM
135}
136