[t] Refactor some namespace pmc tests to use throws_like
[parrot.git] / src / pmc / parrotthread.pmc
blob262d2405a4391089abd99a3d6b2f40db74adf3e9
1 /*
2 Copyright (C) 2001-2007, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/parrotthread.pmc - Threaded Interpreter
9 =head1 DESCRIPTION
11 ParrotThread extends ParrotInterpreter to provide a threaded interpreter
12 which supports:
14     new P2, "ParrotThread"        # create new threaded interp
15     find_method P0, P2, "thread3" # thread-run function
16     find_global P5, "_th1"        # locate thread function
17     invoke                        # run thread
19     set I0, P2                    # get thread id
21 and these methods:
23     thread1
24     thread2
25     thread3                   # start thread of type 1..3
26     join
27     detach
28     yield
29     kill
31 =head2 Methods
33 =over 4
35 =cut
39 #include "parrot/embed.h"
41 #define PMC_interp(x) ((Parrot_ParrotInterpreter_attributes *)PMC_data(x))->interp
44  * can't do multi-threaded GC yet
45  * XXX a quick hack to pass the few tests
46  */
47 static void
48 stop_GC(Interp *parent, Interp *thread)
50 #if 0
51     Parrot_block_GC_mark(parent);
52     Parrot_block_GC_mark(thread);
53     Parrot_block_GC_sweep(parent);
54     Parrot_block_GC_sweep(thread);
55 #endif
58 /* XXX FIXME probably not the best interface [see also list post of
59    coke's]
60  */
62 static INTVAL do_thread_run(PARROT_INTERP, PMC *thread,
63                             INTVAL clone_flags, PMC *sub, PMC *args) {
64     INTVAL tid = VTABLE_get_integer(interp, thread);
66     clone_interpreter(PMC_interp(thread), interp, clone_flags);
68     interp->flags &= ~PARROT_THR_COPY_INTERP; /* XXX */
69     pt_thread_run(interp, thread, sub, args);
71     pmc_reuse(interp, thread, enum_class_ParrotRunningThread, 0);
73     PObj_custom_mark_CLEAR(thread);
74     VTABLE_set_integer_native(interp, thread, tid);
76     return tid;
79 static INTVAL do_thread_run_clone_default(PARROT_INTERP,
80                                           PMC *thread, PMC *sub, PMC *args) {
81     return do_thread_run(interp, thread, PARROT_CLONE_DEFAULT, sub, args);
85 pmclass ParrotThread extends ParrotInterpreter no_ro {
89 =item C<thread_id = thread.'run'(CLONE_FLAGS, sub, args...)>
91 Run the thread. This object is morphed into an appropriate
92 ParrotRunningThread PMC.  The CLONE_FLAGS are or'd together values
93 taken from C<cloneflags.pasm>.
95 =item C<thread_id = thread.'run_clone'(sub, args...)>
97 Equivalent to calling run with PARROT_CLONE_DEFAULT.
99 =cut
103     void class_init() {
104         const int typ = enum_class_ParrotThread;
106         register_nci_method(INTERP, typ,
107                 F2DPTR(do_thread_run), "run", "IJOIP@");
109         /* XXX appropriate name given that this won't clone globals? */
110         register_nci_method(INTERP, typ,
111                 F2DPTR(do_thread_run_clone_default), "run_clone", "IJOP@");
112     }
116 =item C<void init()>
118 Initializes the thread.
120 =cut
124     VTABLE void init() {
125         /* protect interpreter creation and list handling */
126         LOCK(interpreter_array_mutex);
128         SUPER();
129         pt_add_to_interpreters(INTERP, PMC_interp(SELF));
131         UNLOCK(interpreter_array_mutex);
133         /* can't allow GC runs for now */
134         stop_GC(INTERP, PMC_interp(SELF));
135     }
139 =item C<void init_pmc(PMC *parent)>
141 Create a new thread by cloning the passed interpreter.
143 =cut
147     VTABLE void init_pmc(PMC *parent) {
148         LOCK(interpreter_array_mutex);
149         SUPER(parent);
151         pt_add_to_interpreters(PMC_interp(parent),
152                                PMC_interp(SELF));
154         UNLOCK(interpreter_array_mutex);
156         /* can't allow GC runs for now */
157         stop_GC(INTERP, PMC_interp(SELF));
158     }
163 =back
165 =cut
170  * Local variables:
171  *   c-file-style: "parrot"
172  * End:
173  * vim: expandtab shiftwidth=4:
174  */