Just trying to make this whole manual make more sense.
[charm.git] / doc / converse / threads.tex
1 \chapter{Threads}
2
3 The calls in this chapter can be used to put together runtime systems
4 for languages that support threads.
5
6 To use the threads package, you must include {\tt converse.h} and link
7 with the converse library.  Note: threads are not implemented on all
8 hardware platforms.  Although a program that calls thread-functions
9 will {em link} on all platforms, it won't necessarily {\tt execute}.
10 Attempting to initialize the threads package on a machine that does
11 not support threads will result in an error message.
12
13 This threads package, like most thread packages, provides a function
14 for creating threads, one for destroying threads, one for explicitly
15 transferring control to another thread, and one for retrieving the
16 currently-executing thread.  Note that these functions do not include
17 any intelligent strategy for choosing which thread executes when: in
18 other words, they provide no scheduler.
19
20 However, though the threads package does not provide an actual
21 scheduler, it does assume that the user is going to need one.
22 Therefore, it defines an interface to which all schedulers can comply.
23 This makes it possible for users to write blocking code (eg, locks,
24 barriers, etc) without knowing exactly how the scheduler will work.
25 The scheduler interface consists of an awaken function and a suspend
26 function, provided by whomever implements the scheduler.  The awaken
27 function is called by the thread user to notify the scheduler that a
28 particular thread wants the CPU.  The scheduler is expected to respond
29 to this by inserting the thread into a ready-queue or something
30 similar.  The suspend function tells the scheduler that the current
31 thread no longer wants the CPU, whereupon the scheduler must choose
32 another thread to execute instead.  No stipulation is made about how
33 the scheduler chooses the thread to execute next, except that the
34 thread must want the CPU. (Eg, somebody must have declared that the
35 thread wants the CPU using the awaken-function.)
36
37 The threads-package makes it possible to associate private data
38 with a thread.  To this end, we provide functions for storing and
39 retrieving arbitrary user data in the thread-object.
40
41 Finally, as a convenience to converse users, we provide a function
42 that causes a thread to be automatically scheduled by the converse
43 scheduler {\tt CsdScheduler}.
44
45 \function{int CthImplemented()}
46 \index{CthImplemented}
47 \desc{Returns true if the current hardware platform supports the threads
48 functions described below.}
49
50 \function{typedef struct CthThreadStruct *CthThread;}
51 \index{CthThread}
52 \desc{This is an opaque type defined in {\tt converse.h}.  It represents
53 a first-class thread object.  No information is publicized about the
54 contents of a CthThreadStruct.}
55
56 \function{typedef void (CthVoidFn)();}
57 \index{CthVoidFn}
58 \desc{This is a type defined in {\tt threads.h}.  It represents
59 a function that returns nothing.}
60
61 \function{typedef CthThread (CthThFn)();}
62 \index{CthThFn}
63 \desc{This is a type defined in {\tt threads.h}.  It represents
64 a function that returns a CthThread.}
65
66 \function{void CthInit()}
67 \index{CthInit}
68 \desc{Caution: you must call either {\tt ConverseInit} {\tt or} {\tt
69 CthInit} before calling any of the thread functions described below,
70 but you must {\tt not} call both.}
71
72 \function{CthThread CthSelf()}
73 \index{CthSelf}
74 \desc{Returns the currently-executing thread.  Note: even the initial
75 flow of control that inherently existed when the program began
76 executing {\tt main} counts as a thread.  You may retrieve that thread
77 object using {\tt CthSelf} and use it like any other.}
78
79 \function{void CthResume(CthThread t)}
80 \index{CthResume}
81 \desc{Immediately transfers control to thread {\tt t}.  Note:
82 normally, the user of a thread package wouldn't explicitly choose
83 which thread to transfer to.  Instead, the user would rely upon a
84 scheduler to choose the next thread.  Therefore, this routine is
85 primarily intended for people who are implementing schedulers, not for
86 end-users.  End-users should probably call {\tt CthSuspend} or {\tt
87 CthAwaken} (see below).  Likewise, programmers implementing locks,
88 barriers, and other synchronization devices should also probably
89 rely on {\tt CthSuspend} and {\tt CthAwaken}.}
90
91 \function{CthThread CthCreate(CthVoidFn fn, void *arg, int size)}
92 \index{CthCreate}
93 \desc{Creates a new thread object.  The thread is not given control
94 yet.  The thread is not passed to any scheduler.  When (and if) the
95 thread eventually receives control, it will begin executing the
96 specified function {\tt fn} with the specified argument.  The {\tt size}
97 parameter specifies the stack size in bytes, 0 means use the default
98 size.
99
100 Caution: almost all threads are created with CthCreate, but not all.
101 In particular, the one initial thread of control that came into
102 existence when your program was first {\tt exec}'d was not created
103 with {\tt CthCreate}, but it can be retrieved (say, by calling {\tt
104 CthSelf} in {\tt main}), and it can be used like any other {\tt
105 CthThread}.}
106
107 \function{void CthFree(CthThread t)}
108 \index{CthFree}
109 \desc{Frees thread {\tt t}.  You may ONLY free the
110 currently-executing thread (yes, this sounds strange, it's
111 historical).  Naturally, the free will actually be postponed until the
112 thread suspends.  This is how a thread terminates itself: it calls
113 {\tt CthFree(CthSelf())}, then gives up control to another thread.}
114
115 \function{void CthSuspend()}
116 \index{CthSuspend}
117 \desc{This is part of the scheduler-interface.  When a scheduler is
118 being used, threads should call {\tt CthSuspend} when they wish to
119 give up control of the CPU.  {\tt CthSuspend} will then automatically
120 transfer control to some other thread that wants the CPU.  {\tt
121 CthSuspend} will select the thread to transfer control to by calling a
122 user-supplied ``choose-next'' function (see {\tt CthSetStrategy}
123 below).}
124
125 \function{void CthAwaken(CthThread t)}
126 \index{CthAwaken}
127 \desc{This is part of the scheduler-interface.  When a scheduler is
128 being used, this function should be used to notify the scheduler that
129 thread {\tt t} wants the CPU.  This will enable the scheduler to
130 select thread {\tt t} for execution at some point in the future.
131 In actuality, {\tt CthAwaken} simply calls the user-supplied ``awaken''
132 function (see {\tt CthSetStrategy} below).  It is illegal to call
133 {\tt CthAwaken} on a thread which has already been awakened, unless
134 the thread has been scheduled since the last awaken.}
135
136 \function{void CthSetStrategy(CthThread t, CthVoidFn awakenfn, CthThFn choosefn)}
137 \index{CthSetStrategy}
138 \desc{This is part of the scheduler-interface.  It should be used by
139 the creator of thread {\tt t} to specify the scheduling functions to
140 be used for thread {\tt t}.  The scheduling functions must have the
141 following prototypes:
142 \begin{itemize}
143
144 \item{{\tt void awakenfn(CthThread t);}}
145
146 \item{{\tt CthThread choosefn();}}
147
148 \end{itemize}
149 These functions must be provided on a per-thread basis.  (Eg, if you
150 {\tt CthAwaken} a thread {\tt X}, then {\tt X}'s {\tt awakenfn} will
151 be called.  If a thread {\tt Y} calls {\tt CthSuspend}, then thread
152 {\tt Y}'s {\tt choosefn} will be called to pick the next thread.)  Of
153 course, you may use the same functions for all threads (the common
154 case), but the specification on a per-thread basis gives you maximum
155 flexibility in controlling scheduling.
156
157 A final caution about the {\tt choosefn}: it may only return a thread
158 that wants the CPU, eg, a thread that has been awakened using the {\tt
159 awakefn}.  If no such thread exists, if the {\tt choosefn} cannot
160 return an awakened thread, then it must not return at all: instead, it
161 must wait until, by means of some pending IO event, a thread becomes
162 awakened (pending events could be asynchonous disk reads, networked
163 message receptions, signal handlers, etc).  For this reason, many
164 schedulers perform the task of polling the IO devices as a side
165 effect.  If handling the IO event causes a thread to be awakened, then
166 the choosefn may return that thread.  If no pending events exist, then
167 all threads will remain permanently blocked, the program is therefore
168 done, and the {\tt choosefn} should call {\tt exit}.
169
170 There is one minor exception to the rule stated above (``the scheduler
171 may not resume a thread unless it has been declared that the thread
172 wants the CPU using the {\tt awakefn}'').  If a thread {\tt t} is
173 part of the scheduling module, it is permitted for the scheduling
174 module to resume {\tt t} whenever it so desires: presumably, the
175 scheduling module knows when its threads want the CPU.}
176
177 \function{void CthYield()}
178 \index{CthYield}
179 \desc{This function is part of the scheduler-interface.  It simply
180 executes {\tt \{ CthAwaken(CthSelf()); CthSuspend(); \} }.  This combination
181 gives up control temporarily, but ensures that control will eventually
182 return.}
183
184 \internal{
185 \function{void CthSetVar(CthThread t, void **var, void *val)}
186 \desc{Specifies that the global variable pointed to by {\tt
187 var} should be set to value {\tt val} whenever thread {\tt t} is
188 executing.  {\tt var} should be of type {\tt void *}, or at least
189 should be coercible to a {\tt void *}.  This can be used to associate
190 thread-private data with thread {\tt t}.
191
192 it is intended that this function be used as follows:}
193
194 \begin{verbatim}
195     /* User defines a struct th_info containing all the thread-private  */
196     /* data he wishes to associate with threads.  He also defines       */
197     /* a global variable 'current_thread_info' which will always hold   */
198     /* the th_info of the currently-executing thread.                   */
199     struct th_info { ... } *current_thread_info;
200
201     /* User creates a thread 't', and allocates a block of memory       */
202     /* 'tinfo' to hold the thread's private data.  User tells the       */
203     /* system that whenever thread 't' is running, the global variable  */
204     /* 'current_thread_info' should be set to 'tinfo'.  Thus, thread    */
205     /* 't' can access its private data just by dereferencing            */
206     /* 'current_thread_info'.                                           */
207     t = CthCreate( ... );
208     tinfo = (struct th_info *)malloc(sizeof(struct th_info));
209     CthSetVar(t, &current_thread_info, tinfo);
210 \end{verbatim}
211
212 \desc{Note: you can use CthSetVar multiple times on a thread, thereby
213 attaching multiple data items to it.  However, each data item slows
214 down context-switch to that thread by a tiny amount.  Therefore, a
215 module should ideally attach no more than one data item to a thread.
216 We allow multiple data items to be attached so that independent
217 modules can attach data to a thread without interfering with each
218 other.}
219
220 \function{void *CthGetVar(CthThread t, void **var)}
221 \desc{This makes it possible to retrieve values previously stored with
222 {\tt CthSetVar} when {\tt t} is {\it not} executing.  Returns the value
223 that {\tt var} will be set to when {\tt t} is running.}
224 }
225
226 \function{void CthSetStrategyDefault(CthThread t)}
227 \index{CthSetStrategyDefault}
228 \desc{This the simple scheduler provided to converse users as a
229 convenience.  Calling this function on a thread {\tt t} causes thread
230 {\tt t} to be scheduled by the built-in converse scheduler {\tt
231 CsdScheduler}.  Awakening thread {\tt t} will cause it to be inserted
232 into the {\tt CsdScheduler} queue, and it will then be resumed when it
233 gets to the head of the queue.  If it then suspends, it will return
234 control to the thread running the {\tt CsdScheduler}.}
235