File: vthread.3

package info (click to toggle)
sfio 2000-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 2,984 kB
  • ctags: 3,358
  • sloc: ansic: 35,607; makefile: 523; sh: 235
file content (243 lines) | stat: -rw-r--r-- 7,838 bytes parent folder | download | duplicates (2)
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
.TH LIBVTHREAD 3
.SH NAME
\fBVthread\fR \- portable threads
.SH SYNOPSIS
.de Tp
.fl
.ne 2
.TP
..
.de Ss
.fl
.ne 2
.SS "\\$1"
..
.de Cs
.nf
.ft 5
..
.de Ce
.ft 1
.fi
..
.ta 1.0i 2.0i 3.0i 4.0i 5.0i
.Cs
#include <vthread.h>
.Ce
.Ss "VTHREAD TYPES"
.Cs
Void_t*;
Vthread_t;
Vtmutex_t;
Vtonce_t;
.Ce
.Ss "THREAD MANAGEMENT"
.Cs
Vthread_t*  vtopen(Vthread_t* vt, int flags);
int         vtclose(Vthread_t* vt);
int         vtset(Vthread_t* vt, int type, Void_t* val);
Vthread_t*  vtself();
int         vtrun(Vthread_t* vt, Void_t*(*startf)(Void_t*), Void_t* arg);
int         vtwait(Vthread_t* vt);
int         vtkill(Vthread_t* vt);
.Ce
.Ss "MUTEX MANAGEMENT"
.Cs
Vtmutex_t*  vtmtxopen(Vtmutex_t* mtx, int flags);
int         vtmtxclose(Vtmutex_t* mtx);
int         vtmtxlock(Vtmutex_t* mtx);
int         vtmtxtrylock(Vtmutex_t* mtx);
int         vtmtxunlock(Vtmutex_t* mtx);
int         vtmtxclrlock(Vtmutex_t* mtx);
.Ce
.Ss "EXECUTING EXACTLY ONCE"
.Cs
#define     VTONCE_INITDATA
int         vtonce(Vtonce_t* once, void(*func)() );
.Ce
.Ss "GETTING STATUS"
.Cs
int         vtstatus(Vthread_t* vt);
int         vterror(Vthread_t* vt);
int         vtmtxerror(Vtmutex_t* mtx);
int         vtonceerror(Vtonce_t* once);
.Ce
.SH DESCRIPTION
.PP
\fIVthread\fP provides a portable set of functions to create
and manage threads within a single process. The restriction to
a single process allows portable and efficient implementations of
mutexes on top of native primitives available on different platforms.
The mutex interface is kept simple by restricting mutexes to be of the
recursive or counting type.

.PP
.Ss "VTHREAD TYPES"

.PP
.Ss "  Void_t*"
This type is used to pass objects with unknown type
between different code variety.
\f5Void_t\fP is defined as \f5void\fP for ANSI-C and C++
and \f5char\fP for other compilation environments.
.PP
.Ss "  Vthread_t"
This is the type of a thread handle.
.PP
.Ss "  Vtmutex_t"
This is the type of a mutex.
.PP
.Ss "  Vtonce_t"
This is the type of a structure used to
execute certain actions exactly once per process
no matter how many attempts to do so are made from different threads.

.PP
.Ss "THREAD MANAGEMENT"

.PP
.Ss "  Vthread_t* vtopen(Vthread_t* vt, int flags)"
This function creates a new thread handle or renews an existing one.
It returns the resulting thread handle or \f5NULL\fP on error.
.Tp
\f5vt\fP:
If \f5vt\fP is \f5NULL\fP, a new thread handle is created.
In this case, the bits \f5VT_INIT\fP and \f5VT_FREE\fP will be
added to \f5flags\fP (below).
If \f5vt\fP is not \f5NULL\fP, \f5vt\fP is an existing thread to be renewed.
In this case, if the thread is running, it will be waited until execution finishes
before renewing.
.Tp
\f5flags\fP:
The bit \f5VT_INIT\fP indicates that the handle should be initialized.
Otherwise, the handle is assumed to have been initialized already.
The bit \f5VT_FREE\fP indicates that the space occupied by the
handle was obtained via \f5malloc()\fP and can be freed when
the handle is closed.
.PP
.Ss "  int vtclose(Vthread_t* vt)"
This function closes the handle \f5vt\fP and also frees it if appropriate (see vtopen()).
If currently running, closing is done only after execution finishes.
This function returns \f50\fP on success and \f5-1\fP on error.
.PP
.Ss "  int vtset(Vthread_t* vt, int type, Void_t* val);"
This function sets certain attributes of the thread \f5vt\fP.
It returns \f50\fP on success and \f5-1\fP on error.
.Tp
\f5type\fP:
This currently can be only \f5VT_STACK\fP to set the execution stack size
for the thread \f5vt\fP. In the case, the stack size is \f5(size_t)val\fP.
.PP
.Ss "  Vthread_t* vtself();"
This function returns the handle of the calling thread.
.PP
.Ss "  int vtrun(Vthread_t* vt, Void_t*(*startf)(Void_t*), Void_t* arg);"
This function starts the thread running with the call \f5(*startf)(arg)\fP.
It returns \f50\fP on success and \f5-1\fP on error.
.PP
.Ss "  int vtwait(Vthread_t* vt)"
This function waits for the termination of the execution of
the thread \f5vt\fP if currently running.
It returns \f50\fP on success and \f5-1\fP on error.
.PP
.Ss "  int vtkill(Vthread_t* vt)"
This function cancels the execution of the thread \f5vt\fP if currently running.
It returns \f50\fP on success and \f5-1\fP on error.

.PP
.Ss "MUTEX MANAGEMENT"

Mutexes are recursive. That is, each mutex maintains a lock count.
A thread that successfully locks a mutex can relock it as often as needed.
Each successful locking attempt increases the lock count by one.
Only the thread that owns the lock on a mutex can unlock it.
Each successful unlocking attempt decreases the lock count by one.

.PP
.Ss "  Vtmutex_t* vtmtxopen(Vtmutex_t* mtx, int flags);"
This function creates a new mutex or renews an existing mutex structure.
In the latter case, the mutex structure should not be currently locked
or some undefined behavior will result.
The function returns the resulting mutex or \f5NULL\fP on error.
.Tp
\f5mtx\fP:
If \f5mtx\fP is \f5NULL\fP, a new mutex is created.
In this case, the bits \f5VT_INIT\fP and \f5VT_FREE\fP will be
added to \f5flags\fP (below).
If \f5mtx\fP is not \f5NULL\fP, \f5mtx\fP is an existing mutex to be renewed.
.Tp
\f5flags\fP:
The bit \f5VT_INIT\fP indicates that the mutex should be initialized.
Otherwise, the mutex is assumed to have been initialized already.
The bit \f5VT_FREE\fP indicates that the space occupied by the
mutex was obtained via \f5malloc()\fP and can be freed when
the mutex is closed.
.PP
.Ss "  int vtmtxclose(Vtmutex_t* mtx);"
This function clears the lock count of the mutex \f5mtx\fP, then closes it.
It returns \f50\fP on success and \f5-1\fP on error.
.PP
.Ss "  int vtmtxlock(Vtmutex_t* mtx);"
This function attempts to lock the mutex \f5mtx\fP.
If the lock is currently clear, the current thread becomes its owner.
Then, only this thread can relock the mutex as many times as desired.
Any attempt to lock \f5mtx\fP from a different thread will block.
This function returns \f50\fP on success and \f5-1\fP on error.
.PP
.Ss "  int vtmtxtrylock(Vtmutex_t* mtx);"
This function attempts to lock the mutex \f5mtx\fP without blocking.
It returns \f50\fP on success and \f5-1\fP on error.
.PP
.Ss "  int vtmtxunlock(Vtmutex_t* mtx);"
This function attempts to decrease the lock count on
the mutex \f5mtx\fP by one.
Only the thread owning \f5mtx\fP can unlock it.
Any other attempt will result in failure.
The function returns \f50\fP on success and \f5-1\fP on error.
.PP
.Ss "  int vtmtxclrlock(Vtmutex_t* mtx);"
This function attempts to clear the lock on
the mutex \f5mtx\fP, i.e., to reset the lock count to zero.
Only the thread owning \f5mtx\fP can clear it.
Any other attempt will result in failure.
The function returns \f50\fP on success and \f5-1\fP on error.

.PP
.Ss "EXECUTING EXACTLY ONCE"

.PP
.Ss "  VTONCE_INITDATA"
This macro is used to initialize a \f5Vtonce_t\fP structure
in the following manner:
.nf
.ft 5
    Vtonce_t once = VTONCE_INITDATA;
.ft 1
.fi
.PP
.Ss "  int vtonce(Vtonce_t* once, void(*func)() );"
This function ensures that the call \f5(*func)()\fP
is made exactly once per process and \f5once\fP structure
regardless of how many attempts are made.
It is useful for initialization of shared data across threads.
It returns \f50\P on success and \f5-1\fP on error.

.PP
.Ss "GETTING STATUS"

.PP
.Ss "  Void_t* vtstatus(Vthread_t* vt);"
This function returns the exit status of \f5vt\fP after execution finishes.
.PP
.Ss "  int vterror(Vthread_t* vt);"
This function returns the error status of \f5vt\fP after a failed operation.
.PP
.Ss "  int vtmtxerror(Vtmutex_t* mtx);"
This function returns the error status of \f5mtx\fP after a failed operation.
.PP
.Ss "  int vtonceerror(Vtonce_t* once);"
This function returns the error status of \f5once\fP after a failed operation.

.PP
.SH AUTHOR
Kiem-Phong Vo, kpv@research.att.com