-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathlksmith.h
217 lines (193 loc) · 6.06 KB
/
lksmith.h
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*
* vim: ts=8:sw=8:tw=79:noet
*
* Copyright (c) 2011-2012, the Locksmith authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LKSMITH_H
#define LKSMITH_H
#include <stdint.h> /* for uint32_t, etc. */
#include <unistd.h> /* for size_t */
#ifdef __cplusplus
extern "C" {
#endif
struct lksmith_cond;
/******************************************************************
* Locksmith macros
*****************************************************************/
/** The current Locksmith version.
*
* Format: the first 16 bits are the major version; the second 16 bits are the
* minor version. Changes in the major version break the ABI; minor version
* changes may add to the ABI, but they never break it.
*
* Use lksmith_verion_to_str to get a human-readable version.
*/
#define LKSMITH_API_VERSION 0x0001000
/**
* Maximum length of a thread name, including the terminating NULL byte.
*/
#define LKSMITH_THREAD_NAME_MAX 16
/******************************************************************
* Locksmith API
*****************************************************************/
/**
* Get the current Locksmith API version
*
* @return The current locksmith API version
*/
uint32_t lksmith_get_version(void);
/**
* Convert the current Locksmith API version to a human-readable string.
* This function is thread-safe.
*
* @param ver A locksmith API version
* @param str (out parameter) buffer to place the version string
* @param str_len Length of the str buffer
*
* @return 0 on success; -ENAMETOOLONG if the provided buffer
* length was too short; -EIO if another failure happened.
*/
int lksmith_verion_to_str(uint32_t ver, char *str, size_t str_len);
/**
* Initialize thread-local storage and function stubs.
* TODO: move this to internal header.
*
* @return 0 on success; negative error code otherwise.
*/
int init_tls(void);
/**
* Initialize a locksmith lock. This function is optional.
*
* @param ptr pointer to the lock to initialize
* @param recursive 1 to allow recursive locks; 0 otherwise
* @param sleeper 1 if this lock is a sleeper; 0 otherwise
*
* @return 0 on success; error code otherwise
*/
int lksmith_optional_init(const void *ptr, int recursive, int sleeper);
/**
* Destroy a lock.
*
* @param ptr pointer to the lock to destroy
*
* @return 0 if the lock was destroyed;
* ENOENT if we're not aware of any such lock
*/
int lksmith_destroy(const void *ptr);
/**
* Destroy a lock.
*
* @param ptr pointer to the lock to destroy
*/
void lksmith_postdestroy(const void *ptr);
/**
* Perform some error checking before taking a lock.
*
* @param ptr pointer to the lock
* @param sleeper 1 if this lock is a sleeper; 0 otherwise
*
* @return 0 if we should continue with the lock; error code
* otherwise. We may print an error even if 0 is
* returned.
*/
int lksmith_prelock(const void *ptr, int sleeper);
/**
* Take a lock.
*
* @param ptr pointer to the lock.
*/
void lksmith_postlock(const void *ptr, int error);
/**
* Determine if it's safe to release a lock.
*
* @param ptr pointer to the lock.
*
* @return 0 on success, or the error code.
*/
int lksmith_preunlock(const void *ptr);
/**
* Release a lock.
*
* @param ptr pointer to the lock.
*/
void lksmith_postunlock(const void *ptr);
/**
* Check if the current thread holds the given lock.
*
* @param ptr pointer to the lock to check for
*
* @return -1 if the thread does not hold the lock;
* 0 if the thread holds the lock;
* a positive error code otherwise.
*/
int lksmith_check_locked(const void *ptr);
/**
* Register a given condition variable as about to wait.
*
* @param cond pointer to the condition variable
* @param mutex pointer to the mutex to be used with cond
* @param out (out param) on success, a pointer to be used
* with lksmith_cond_postwait.
*
* @return 0 on success; error code otherwise.
*/
int lksmith_cond_prewait(const void *cond, const void *mutex,
struct lksmith_cond **out);
/**
* Unregister a given condition variable as about to wait.
*
* @param cnd pointer returned from lksmith_cond_prewait
*/
void lksmith_cond_postwait(struct lksmith_cond *cnd);
/**
* Destroy a given condition variable.
*
* @param cond the condition variable
*/
int lksmith_cond_predestroy(const void *cond);
/**
* Set the thread name.
*
* @param name The name to use for this thread.
* This string will be deep-copied.
* The copy will be truncated to LKSMITH_THREAD_NAME_MAX
* bytes long, including the terminating null.
*
* @return 0 on success; error code otherwise
*/
int lksmith_set_thread_name(const char * const name);
/**
* Get the thread name.
*
* @return The thread name. This is allocated as a thread-local
* string. Returns NULL if we failed to allocate
* thread-local data.
*/
const char* lksmith_get_thread_name(void);
#ifdef __cplusplus
}
#endif
#endif