1
1
.. highlightlang :: c
2
2
3
- .. comment: affected files: data\refcounts.dat
4
- .. comment: affected files: c-api\stackless.rst
5
- .. comment: to do: link c-api\stackless.rst in somewhere
6
- .. comment: to do: generate new docs
3
+ | SLP | C-API
4
+ ===========
5
+
6
+ | SLP | provides the following C functions.
7
7
8
8
Tasklets
9
9
--------
@@ -18,7 +18,7 @@ Tasklets
18
18
exception is set, which is in contrast elsewhere in the function.
19
19
20
20
.. c:function:: int PyTasklet_Setup(PyTaskletObject *task, PyObject *args, PyObject *kwds)
21
-
21
+
22
22
Binds a tasklet function to parameters, making it ready to run and inserts in
23
23
into the runnables queue. Returns ``0 `` if successful or ``-1 `` in the case of failure.
24
24
@@ -33,6 +33,19 @@ Tasklets
33
33
the call soft switched, ``0 `` if the call hard switched and -1 in the case of
34
34
failure.
35
35
36
+ .. c :function :: int PyTasklet_Switch (PyTaskletObject *task)
37
+
38
+ Forces *task * to run immediately. The previous tasklet is paused.
39
+ Returns ``0 `` if successful, and ``-1 `` in the
40
+ case of failure.
41
+
42
+ .. c :function :: int PyTasklet_Switch_nr (PyTaskletObject *task)
43
+
44
+ Forces *task * to run immediately, soft switching if possible.
45
+ The previous tasklet is paused. Returns ``1 `` if
46
+ the call soft switched, ``0 `` if the call hard switched and -1 in the case of
47
+ failure.
48
+
36
49
.. c :function :: int PyTasklet_Remove (PyTaskletObject *task)
37
50
38
51
Removes *task * from the runnables queue. Be careful! If this tasklet has a C
@@ -45,41 +58,35 @@ Tasklets
45
58
Insert *task * into the runnables queue, if it isn't already there. If it is
46
59
blocked or dead, the function returns ``-1 `` and a :exc: `RuntimeError ` is raised.
47
60
48
- .. c :function :: PyObject *PyTasklet_Become (PyTaskletObject *self, PyObject *retval)
49
-
50
- Use of this API function is undocumented and unrecommended.
51
-
52
- .. deprecated :: 2.5
53
- Proved problematic in production use and are pending removal.
54
-
55
- .. c :function :: PyObject* PyTasklet_Capture (PyTaskletObject *self, PyObject *retval)
56
-
57
- Use of this API function is undocumented and unrecommended.
58
-
59
- .. deprecated :: 2.5
60
- Proved problematic in production use and are pending removal.
61
-
62
61
.. c :function :: int PyTasklet_RaiseException (PyTaskletObject *self, PyObject *klass, PyObject *args)
63
62
64
63
Raises an instance of the *klass * exception on the *self * tasklet. *klass * must
65
64
be a subclass of :exc: `Exception `. Returns ``1 `` if the call soft switched, ``0 ``
66
65
if the call hard switched and ``-1 `` in the case of failure.
67
66
68
67
.. note :: Raising :exc:`TaskletExit` on a tasklet can be done to silently kill
69
- it, see :c:func: `PyTasklet_Kill `.
68
+ it, see :c:func: `PyTasklet_Kill `.
69
+
70
+ .. c :function :: int PyTasklet_Throw (PyTaskletObject *self, int pending, PyObject *exc, PyObject *val, PyObject *tb)
71
+
72
+ Raises (*exc *, *val *, *tb *) on the *self* tasklet. This is the C equivalent to
73
+ method :py:meth:`tasklet.throw`. Returns ``1`` if the call soft switched, ``0``
74
+ if the call hard switched and ``-1`` in the case of failure.
70
75
71
76
.. c:function:: int PyTasklet_Kill(PyTaskletObject *self)
72
-
77
+
73
78
Raises :exc: `TaskletExit ` on tasklet *self *. This should result in *task * being
74
- silently killed. Returns ``1 `` if the call soft switched, ``0 `` if the call hard
79
+ silently killed. (This exception is ignored by tasklet_end and
80
+ does not invoke main as exception handler.)
81
+ Returns ``1`` if the call soft switched, ``0`` if the call hard
75
82
switched and ``-1`` in the case of failure.
76
83
77
84
.. c:function:: int PyTasklet_GetAtomic(PyTaskletObject *task)
78
85
79
86
Returns ``1 `` if *task * is atomic, otherwise ``0 ``.
80
87
81
88
.. c :function :: int PyTasklet_SetAtomic (PyTaskletObject *task, int flag)
82
-
89
+
83
90
Returns ``1 `` if *task * is currently atomic, otherwise ``0 ``. Sets the
84
91
atomic attribute to the logical value of *flag *.
85
92
@@ -129,7 +136,7 @@ Tasklets
129
136
130
137
Returns ``1 `` if *task * is alive (has an associated frame), otherwise
131
138
``0`` if it is dead.
132
-
139
+
133
140
.. c:function:: int PyTasklet_Paused(PyTaskletObject *task)
134
141
135
142
Returns ``1 `` if *task * is paused, otherwise ``0 ``. A tasklet is paused if it is
@@ -151,7 +158,7 @@ Tasklets
151
158
Channels
152
159
--------
153
160
154
- .. c :function :: PyChannelObject* PyChannel_New (PyTypeObject *type)
161
+ .. c :function :: PyChannelObject* PyChannel_New (PyTypeObject *type)
155
162
156
163
Return a new channel object, or *NULL * in the case of failure. *type * must be
157
164
derived from :c:type: `PyChannel_Type ` or be *NULL *, otherwise a :exc: `TypeError `
@@ -184,6 +191,11 @@ Channels
184
191
Returns ``0 `` if successful or ``-1 `` in the case of failure. An instance of the
185
192
exception type *klass * is raised on the first tasklet blocked on channel *self *.
186
193
194
+ .. c :function :: int PyChannel_SendThrow (PyChannelObject *self, PyObject *exc, PyObject *val, PyObject *tb)
195
+
196
+ Returns ``0 `` if successful or ``-1 `` in the case of failure.
197
+ (*exc *, *val *, *tb *) is raised on the first tasklet blocked on channel *self*.
198
+
187
199
.. c:function:: PyObject *PyChannel_GetQueue(PyChannelObject *self)
188
200
189
201
Returns the first tasklet in the channel *self *'s queue, or *NULL * in the case
@@ -255,6 +267,23 @@ stackless module
255
267
256
268
Get the currently running tasklet, that is, "yourself".
257
269
270
+ .. c:function:: long PyStackless_GetCurrentId()
271
+
272
+ Get a unique integer ID for the current tasklet
273
+
274
+ Threadsafe.
275
+
276
+ This is useful for benchmarking code that
277
+ needs to get some sort of a stack identifier and must
278
+ not worry about the GIL being present and so on.
279
+
280
+ .. note::
281
+
282
+ 1. the "main" tasklet on each thread will have the same id,
283
+ even if a proper tasklet has not been initialized.
284
+
285
+ 2. IDs may get recycled for new tasklets.
286
+
258
287
.. c:function:: PyObject *PyStackless_RunWatchdog(long timeout)
259
288
260
289
Runs the scheduler until there are no tasklets remaining within it, or until
@@ -274,28 +303,28 @@ stackless module
274
303
Wraps :c:func:`PyStackless_RunWatchdog`, but allows its behaviour to be
275
304
customised by the value of *flags* which may contain any of the following
276
305
bits:
277
-
306
+
278
307
``Py_WATCHDOG_THREADBLOCK``
279
308
Allows a thread to block if it runs out of tasklets. Ideally
280
309
it will be awakened by other threads using channels which its
281
310
blocked tasklets are waiting on.
282
-
311
+
283
312
``Py_WATCHDOG_SOFT``
284
313
Instead of interrupting a tasklet, we wait until the
285
314
next tasklet scheduling moment to return. Always returns
286
315
*Py_None*, as everything is in order.
287
-
316
+
288
317
``Py_WATCHDOG_IGNORE_NESTING``
289
318
Allows interrupts at all levels, effectively acting as
290
319
though the *ignore_nesting* attribute were set on all
291
320
tasklets.
292
-
321
+
293
322
``Py_WATCHDOG_TIMEOUT``
294
323
Interprets *timeout* as a fixed run time, rather than a
295
324
per-tasklet run limit. The function will then attempt to
296
325
interrupt execution once this many total opcodes have
297
326
been executed since the call was made.
298
-
327
+
299
328
debugging and monitoring functions
300
329
----------------------------------
301
330
0 commit comments