1 #include "rust_internal.h"
5 KLOG(this, kern, __VA_ARGS__)
6 #define KLOG_ERR_(field, ...) \
7 KLOG_LVL(this, field, log_err, __VA_ARGS__)
9 rust_kernel::rust_kernel(rust_srv *srv, size_t num_threads) :
14 num_threads(num_threads),
19 isaac_init(this, &rctx);
24 rust_kernel::create_scheduler(int id) {
26 rust_srv *srv = this->srv->clone();
27 rust_scheduler *sched =
28 new (this, "rust_scheduler") rust_scheduler(this, srv, id);
29 KLOG_("created scheduler: " PTR ", id: %d, index: %d",
30 sched, id, sched->list_index);
31 _kernel_lock.signal_all();
32 _kernel_lock.unlock();
37 rust_kernel::destroy_scheduler(rust_scheduler *sched) {
39 KLOG_("deleting scheduler: " PTR ", name: %s, index: %d",
40 sched, sched->name, sched->list_index);
41 rust_srv *srv = sched->srv;
44 _kernel_lock.signal_all();
45 _kernel_lock.unlock();
48 void rust_kernel::create_schedulers() {
49 KLOG_("Using %d scheduler threads.", num_threads);
51 for(size_t i = 0; i < num_threads; ++i) {
52 threads.push(create_scheduler(i));
56 void rust_kernel::destroy_schedulers() {
57 for(size_t i = 0; i < num_threads; ++i) {
58 destroy_scheduler(threads[i]);
63 rust_kernel::log_all_scheduler_state() {
64 for(size_t i = 0; i < num_threads; ++i) {
65 threads[i]->log_state();
70 * Checks for simple deadlocks.
73 rust_kernel::is_deadlocked() {
78 rust_kernel::log(uint32_t level, char const *fmt, ...) {
82 vsnprintf(buf, sizeof(buf), fmt, args);
83 _log.trace_ln(NULL, level, buf);
88 rust_kernel::fatal(char const *fmt, ...) {
92 vsnprintf(buf, sizeof(buf), fmt, args);
93 _log.trace_ln(NULL, (uint32_t)0, buf);
98 rust_kernel::~rust_kernel() {
103 rust_kernel::malloc(size_t size, const char *tag) {
104 return _region.malloc(size, tag);
108 rust_kernel::realloc(void *mem, size_t size) {
109 return _region.realloc(mem, size);
112 void rust_kernel::free(void *mem) {
117 rust_kernel::signal_kernel_lock() {
119 _kernel_lock.signal_all();
120 _kernel_lock.unlock();
123 int rust_kernel::start_task_threads()
125 for(size_t i = 0; i < num_threads; ++i) {
126 rust_scheduler *thread = threads[i];
130 for(size_t i = 0; i < num_threads; ++i) {
131 rust_scheduler *thread = threads[i];
139 rust_kernel::fail() {
140 // FIXME: On windows we're getting "Application has requested the
141 // Runtime to terminate it in an unusual way" when trying to shutdown
143 #if defined(__WIN32__)
146 for(size_t i = 0; i < num_threads; ++i) {
147 rust_scheduler *thread = threads[i];
148 thread->kill_all_tasks();
153 rust_kernel::create_task(rust_task *spawner, const char *name) {
154 scoped_lock with(_kernel_lock);
155 rust_scheduler *thread = threads[isaac_rand(&rctx) % num_threads];
156 rust_task *t = thread->create_task(spawner, name);
157 t->user.id = max_id++;
158 task_table.put(t->user.id, t);
163 rust_kernel::get_task_by_id(rust_task_id id) {
164 scoped_lock with(_kernel_lock);
165 rust_task *task = NULL;
166 // get leaves task unchanged if not found.
167 task_table.get(id, &task);
169 if(task->get_ref_count() == 0) {
170 // this means the destructor is running, since the destructor
171 // grabs the kernel lock to unregister the task. Pretend this
172 // doesn't actually exist.
183 rust_kernel::release_task_id(rust_task_id id) {
184 scoped_lock with(_kernel_lock);
185 task_table.remove(id);
188 void rust_kernel::wakeup_schedulers() {
189 for(size_t i = 0; i < num_threads; ++i) {
190 threads[i]->lock.signal_all();
196 rust_kernel::win32_require(LPCTSTR fn, BOOL ok) {
199 DWORD err = GetLastError();
200 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
201 FORMAT_MESSAGE_FROM_SYSTEM |
202 FORMAT_MESSAGE_IGNORE_INSERTS,
204 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
205 (LPTSTR) &buf, 0, NULL );
206 KLOG_ERR_(dom, "%s failed with error %ld: %s", fn, err, buf);
207 LocalFree((HLOCAL)buf);
217 // indent-tabs-mode: nil
219 // buffer-file-coding-system: utf-8-unix