]> git.lizzy.rs Git - rust.git/blob - src/rt/rust_task.h
6be28f41574c356c18dee2cf2ffaaef99ff048f8
[rust.git] / src / rt / rust_task.h
1 /*
2  *
3  */
4
5 #ifndef RUST_TASK_H
6 #define RUST_TASK_H
7
8 #include <map>
9
10 #include "util/array_list.h"
11
12 #include "context.h"
13 #include "rust_debug.h"
14 #include "rust_internal.h"
15 #include "rust_kernel.h"
16 #include "rust_obstack.h"
17
18 // Corresponds to the rust chan (currently _chan) type.
19 struct chan_handle {
20     rust_task_id task;
21     rust_port_id port;
22 };
23
24 struct rust_closure {
25     const type_desc *td;
26     // ... see trans_closure.rs for full description ...
27 };
28
29 struct rust_boxed_closure {
30     intptr_t ref_count;
31     rust_closure closure;
32 };
33
34 typedef void (*CDECL spawn_fn)(void*, rust_boxed_closure*, void *);
35
36 struct rust_box;
37
38 struct stk_seg {
39     stk_seg *prev;
40     stk_seg *next;
41     uintptr_t end;
42     unsigned int valgrind_id;
43 #ifndef _LP64
44     uint32_t pad;
45 #endif
46
47     uint8_t data[];
48 };
49
50 struct frame_glue_fns {
51     uintptr_t mark_glue_off;
52     uintptr_t drop_glue_off;
53     uintptr_t reloc_glue_off;
54 };
55
56 // portions of the task structure that are accessible from the standard
57 // library. This struct must agree with the std::task::rust_task record.
58 struct rust_task_user {
59     rust_task_id id;
60     intptr_t notify_enabled;   // this is way more bits than necessary, but it
61                                // simplifies the alignment.
62     chan_handle notify_chan;
63     uintptr_t rust_sp;         // Saved sp when not running.
64 };
65
66 // std::lib::task::task_result
67 typedef unsigned long task_result;
68 #define tr_success 0
69 #define tr_failure 1
70
71 // std::lib::task::task_notification
72 //
73 // since it's currently a unary tag, we only add the fields.
74 struct task_notification {
75     rust_task_id id;
76     task_result result; // task_result
77 };
78
79 struct
80 rust_task : public kernel_owned<rust_task>, rust_cond
81 {
82     rust_task_user user;
83
84     RUST_ATOMIC_REFCOUNT();
85
86     // Fields known to the compiler.
87     context ctx;
88     stk_seg *stk;
89     uintptr_t runtime_sp;      // Runtime sp while task running.
90     rust_scheduler *sched;
91     rust_crate_cache *cache;
92
93     // Fields known only to the runtime.
94     rust_kernel *kernel;
95     const char *const name;
96     rust_task_list *state;
97     rust_cond *cond;
98     const char *cond_name;
99     rust_task *supervisor;     // Parent-link for failure propagation.
100     int32_t list_index;
101
102     rust_port_id next_port_id;
103
104     // Keeps track of the last time this task yielded.
105     timer yield_timer;
106
107     // Rendezvous pointer for receiving data when blocked on a port. If we're
108     // trying to read data and no data is available on any incoming channel,
109     // we block on the port, and yield control to the scheduler. Since, we
110     // were not able to read anything, we remember the location where the
111     // result should go in the rendezvous_ptr, and let the sender write to
112     // that location before waking us up.
113     uintptr_t* rendezvous_ptr;
114
115     // This flag indicates that a worker is either currently running the task
116     // or is about to run this task.
117     int running_on;
118     int pinned_on;
119
120     memory_region local_region;
121
122     // Indicates that the task ended in failure
123     bool failed;
124     // Indicates that the task was killed and needs to unwind
125     bool killed;
126     bool propagate_failure;
127
128     lock_and_signal lock;
129
130     hash_map<rust_port_id, rust_port *> port_table;
131
132     rust_obstack dynastack;
133
134     std::map<void *,const type_desc *> local_allocs;
135     uint32_t cc_counter;
136
137     debug::task_debug_info debug;
138
139     // Only a pointer to 'name' is kept, so it must live as long as this task.
140     rust_task(rust_scheduler *sched,
141               rust_task_list *state,
142               rust_task *spawner,
143               const char *name);
144
145     ~rust_task();
146
147     void start(spawn_fn spawnee_fn,
148                rust_boxed_closure *env,
149                void *args);
150     void start();
151     bool running();
152     bool blocked();
153     bool blocked_on(rust_cond *cond);
154     bool dead();
155
156     void *malloc(size_t sz, const char *tag, type_desc *td=0);
157     void *realloc(void *data, size_t sz, bool gc_mem=false);
158     void free(void *p, bool gc_mem=false);
159
160     void transition(rust_task_list *src, rust_task_list *dst);
161
162     void block(rust_cond *on, const char* name);
163     void wakeup(rust_cond *from);
164     void die();
165     void unblock();
166
167     // Print a backtrace, if the "bt" logging option is on.
168     void backtrace();
169
170     // Yields for a specified duration of time.
171     void yield(size_t time_in_ms, bool *killed);
172
173     // Fail this task (assuming caller-on-stack is different task).
174     void kill();
175
176     // Fail self, assuming caller-on-stack is this task.
177     void fail();
178     void conclude_failure();
179     void fail_parent();
180
181     // Disconnect from our supervisor.
182     void unsupervise();
183
184     frame_glue_fns *get_frame_glue_fns(uintptr_t fp);
185     rust_crate_cache * get_crate_cache();
186
187     bool can_schedule(int worker);
188
189     void *calloc(size_t size, const char *tag);
190
191     void pin();
192     void pin(int id);
193     void unpin();
194
195     rust_port_id register_port(rust_port *port);
196     void release_port(rust_port_id id);
197     rust_port *get_port_by_id(rust_port_id id);
198
199     // Use this function sparingly. Depending on the ref count is generally
200     // not at all safe.
201     intptr_t get_ref_count() const { return ref_count; }
202
203     // FIXME: These functions only exist to get the tasking system off the
204     // ground. We should never be migrating shared boxes between tasks.
205     const type_desc *release_alloc(void *alloc);
206     void claim_alloc(void *alloc, const type_desc *tydesc);
207
208     void notify(bool success);
209
210     void *new_stack(size_t stk_sz, void *args_addr, size_t args_sz);
211     void del_stack();
212     void record_stack_limit();
213     void reset_stack_limit();
214     bool on_rust_stack();
215     void check_stack_canary();
216 };
217
218 //
219 // Local Variables:
220 // mode: C++
221 // fill-column: 78;
222 // indent-tabs-mode: nil
223 // c-basic-offset: 4
224 // buffer-file-coding-system: utf-8-unix
225 // End:
226 //
227
228 #endif /* RUST_TASK_H */