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