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