]> git.lizzy.rs Git - rust.git/blob - src/rt/rust_internal.h
889b5f62018457ab36a0f2dd9c3040db7ad7af34
[rust.git] / src / rt / rust_internal.h
1 #ifndef RUST_INTERNAL_H
2 #define RUST_INTERNAL_H
3
4 #ifndef GLOBALS_H
5 // these are defined in two files, and GCC complains.
6 #define __STDC_LIMIT_MACROS 1
7 #define __STDC_CONSTANT_MACROS 1
8 #define __STDC_FORMAT_MACROS 1
9 #endif
10
11 #define ERROR 0
12
13 #include <stdlib.h>
14 #include <stdint.h>
15 #include <inttypes.h>
16 #include <stdarg.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <fcntl.h>
22 #include <math.h>
23
24 #include "rust.h"
25 #include "rand.h"
26 #include "uthash.h"
27 #include "rust_env.h"
28
29 #if defined(__WIN32__)
30 extern "C" {
31 #include <windows.h>
32 #include <tchar.h>
33 #include <wincrypt.h>
34 }
35 #elif defined(__GNUC__)
36 #include <unistd.h>
37 #include <dlfcn.h>
38 #include <pthread.h>
39 #include <errno.h>
40 #include <dirent.h>
41 #else
42 #error "Platform not supported."
43 #endif
44
45 #include "util/array_list.h"
46 #include "util/indexed_list.h"
47 #include "util/synchronized_indexed_list.h"
48 #include "util/hash_map.h"
49 #include "sync/sync.h"
50 #include "sync/timer.h"
51 #include "sync/lock_and_signal.h"
52 #include "sync/lock_free_queue.h"
53
54 struct rust_scheduler;
55 struct rust_task;
56 class rust_log;
57 class rust_port;
58 class rust_kernel;
59 class rust_crate_cache;
60
61 struct stk_seg;
62 struct type_desc;
63 struct frame_glue_fns;
64
65 typedef intptr_t rust_task_id;
66 typedef intptr_t rust_port_id;
67
68 //NDM #ifndef __i386__
69 //NDM #error "Target CPU not supported."
70 //NDM #endif
71
72 #define I(dom, e) ((e) ? (void)0 : \
73          (dom)->srv->fatal(#e, __FILE__, __LINE__, ""))
74
75 #define W(dom, e, s, ...) ((e) ? (void)0 : \
76          (dom)->srv->warning(#e, __FILE__, __LINE__, s, ## __VA_ARGS__))
77
78 #define A(dom, e, s, ...) ((e) ? (void)0 : \
79          (dom)->srv->fatal(#e, __FILE__, __LINE__, s, ## __VA_ARGS__))
80
81 #define K(srv, e, s, ...) ((e) ? (void)0 : \
82          srv->fatal(#e, __FILE__, __LINE__, s, ## __VA_ARGS__))
83
84 #define PTR "0x%" PRIxPTR
85
86 // This drives our preemption scheme.
87
88 static size_t const TIME_SLICE_IN_MS = 10;
89
90 // This accounts for logging buffers.
91
92 static size_t const BUF_BYTES = 2048;
93
94 // The error status to use when the process fails
95 #define PROC_FAIL_CODE 101;
96
97 // Every reference counted object should use this macro and initialize
98 // ref_count.
99
100 #define RUST_REFCOUNTED(T) \
101   RUST_REFCOUNTED_WITH_DTOR(T, delete (T*)this)
102 #define RUST_REFCOUNTED_WITH_DTOR(T, dtor) \
103   intptr_t ref_count;      \
104   void ref() { ++ref_count; } \
105   void deref() { if (--ref_count == 0) { dtor; } }
106
107 #define RUST_ATOMIC_REFCOUNT()                                          \
108     private:                                                            \
109     intptr_t ref_count;                                                 \
110 public:                                                                 \
111  void ref() {                                                           \
112      intptr_t old = sync::increment(ref_count);                         \
113      assert(old > 0);                                                   \
114  }                                                                      \
115  void deref() { if(0 == sync::decrement(ref_count)) { delete this; } }
116
117 template <typename T> struct task_owned {
118     inline void *operator new(size_t size, rust_task *task, const char *tag);
119
120     inline void *operator new[](size_t size, rust_task *task,
121                                 const char *tag);
122
123     inline void *operator new(size_t size, rust_task &task, const char *tag);
124
125     inline void *operator new[](size_t size, rust_task &task,
126                                 const char *tag);
127
128     void operator delete(void *ptr) {
129         ((T *)ptr)->task->free(ptr);
130     }
131 };
132
133 template<class T>
134 class smart_ptr {
135     T *p;
136
137 public:
138     smart_ptr() : p(NULL) {};
139     smart_ptr(T *p) : p(p) { if(p) { p->ref(); } }
140     smart_ptr(const smart_ptr &sp) : p(sp.p) {
141         if(p) { p->ref(); }
142     }
143
144     ~smart_ptr() {
145         if(p) {
146             p->deref();
147         }
148     }
149
150     T *operator=(T* p) {
151         if(this->p) {
152             this->p->deref();
153         }
154         if(p) {
155             p->ref();
156         }
157         this->p = p;
158
159         return p;
160     }
161
162     T *operator->() const { return p; };
163
164     operator T*() const { return p; }
165 };
166
167 template <typename T> struct kernel_owned {
168     inline void *operator new(size_t size, rust_kernel *kernel,
169                               const char *tag);
170
171     void operator delete(void *ptr) {
172         ((T *)ptr)->kernel->free(ptr);
173     }
174 };
175
176 template <typename T> struct region_owned {
177     void operator delete(void *ptr) {
178         ((T *)ptr)->region->free(ptr);
179     }
180 };
181
182 #include "rust_task_list.h"
183
184 // A cond(ition) is something we can block on. This can be a channel
185 // (writing), a port (reading) or a task (waiting).
186
187 struct rust_cond { };
188
189 // Helper class used regularly elsewhere.
190
191 template <typename T> class ptr_vec : public task_owned<ptr_vec<T> > {
192     static const size_t INIT_SIZE = 8;
193     rust_task *task;
194     size_t alloc;
195     size_t fill;
196     T **data;
197 public:
198     ptr_vec(rust_task *task);
199     ~ptr_vec();
200
201     size_t length() {
202         return fill;
203     }
204
205     bool is_empty() {
206         return fill == 0;
207     }
208
209     T *& operator[](size_t offset);
210     void push(T *p);
211     T *pop();
212     T *peek();
213     void trim(size_t fill);
214     void swap_delete(T* p);
215 };
216
217 #include "memory_region.h"
218 #include "rust_srv.h"
219 #include "rust_log.h"
220 #include "rust_kernel.h"
221 #include "rust_scheduler.h"
222
223 struct rust_timer {
224     // FIXME: This will probably eventually need replacement
225     // with something more sophisticated and integrated with
226     // an IO event-handling library, when we have such a thing.
227     // For now it's just the most basic "thread that can interrupt
228     // its associated domain-thread" device, so that we have
229     // *some* form of task-preemption.
230     rust_scheduler *sched;
231     uintptr_t exit_flag;
232
233 #if defined(__WIN32__)
234     HANDLE thread;
235 #else
236     pthread_attr_t attr;
237     pthread_t thread;
238 #endif
239
240     rust_timer(rust_scheduler *sched);
241     ~rust_timer();
242 };
243
244 #include "rust_util.h"
245
246 typedef void CDECL (glue_fn)(void *, void *,
247                              const type_desc **, void *);
248 typedef void CDECL (cmp_glue_fn)(void *, void *,
249                                  const type_desc **,
250                                  void *, void *, int8_t);
251
252 struct rust_shape_tables {
253     uint8_t *tags;
254     uint8_t *resources;
255 };
256
257 struct type_desc {
258     // First part of type_desc is known to compiler.
259     // first_param = &descs[1] if dynamic, null if static.
260     const type_desc **first_param;
261     size_t size;
262     size_t align;
263     glue_fn *take_glue;
264     glue_fn *drop_glue;
265     glue_fn *free_glue;
266     void *unused;
267     glue_fn *sever_glue;    // For GC.
268     glue_fn *mark_glue;     // For GC.
269     uintptr_t unused2;
270     cmp_glue_fn *cmp_glue;
271     const uint8_t *shape;
272     const rust_shape_tables *shape_tables;
273     uintptr_t n_params;
274     uintptr_t n_obj_params;
275
276     // Residual fields past here are known only to runtime.
277     UT_hash_handle hh;
278     size_t n_descs;
279     const type_desc *descs[];
280 };
281
282 extern "C" type_desc *rust_clone_type_desc(type_desc*);
283
284 #include "circular_buffer.h"
285 #include "rust_task.h"
286 #include "rust_port.h"
287 #include "memory.h"
288
289 #include "test/rust_test_harness.h"
290 #include "test/rust_test_util.h"
291 #include "test/rust_test_runtime.h"
292
293 //
294 // Local Variables:
295 // mode: C++
296 // fill-column: 78;
297 // indent-tabs-mode: nil
298 // c-basic-offset: 4
299 // buffer-file-coding-system: utf-8-unix
300 // compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
301 // End:
302 //
303
304 #endif