?? monitor.c
字號:
{ *return_size = sizeof(*params); if (cmon->state == CO_MONITOR_STATE_RUNNING) { bool_t ret; do { ret = iteration(cmon); } while (ret); return CO_RC(OK); } else if (cmon->state == CO_MONITOR_STATE_STARTED) { cmon->state = CO_MONITOR_STATE_RUNNING; iteration(cmon); return CO_RC(OK); } if (cmon->state == CO_MONITOR_STATE_TERMINATED) return CO_RC(INSTANCE_TERMINATED); return CO_RC(ERROR);}co_rc_t co_monitor_create(co_manager_t *manager, co_manager_ioctl_create_t *params, co_monitor_t **cmon_out){ co_symbols_import_t *import = ¶ms->import; co_monitor_t *cmon; co_rc_t rc = CO_RC_OK; cmon = co_os_malloc(sizeof(*cmon)); if (!cmon) { rc = CO_RC(OUT_OF_MEMORY); goto out; } co_memset(cmon, 0, sizeof(*cmon)); cmon->manager = manager; cmon->state = CO_MONITOR_STATE_EMPTY; cmon->id = co_os_current_id(); rc = co_console_create(80, 25, 0, &cmon->console); if (!CO_OK(rc)) goto out_free_monitor; rc = co_os_mutex_create(&cmon->connected_modules_write_lock); if (!CO_OK(rc)) goto out_free_console; rc = co_os_mutex_create(&cmon->linux_message_queue_mutex); if (!CO_OK(rc)) goto out_free_mutex1; rc = co_os_wait_create(&cmon->idle_wait); if (!CO_OK(rc)) goto out_free_mutex2; params->id = cmon->id; cmon->io_buffer = co_os_malloc(CO_VPTR_IO_AREA_SIZE); if (cmon->io_buffer == NULL) { rc = CO_RC(OUT_OF_MEMORY); goto out_free_wait; } co_memset(cmon->io_buffer, 0, CO_VPTR_IO_AREA_SIZE); rc = alloc_shared_page(cmon); if (!CO_OK(rc)) goto out_free_buffer; params->shared_user_address = cmon->shared_user_address; rc = co_queue_init(&cmon->linux_message_queue); if (!CO_OK(rc)) goto out_free_shared_page; rc = co_monitor_os_init(cmon); if (!CO_OK(rc)) goto out_free_linux_message_queue; cmon->core_vaddr = import->kernel_start; cmon->core_pages = (import->kernel_end - import->kernel_start + CO_ARCH_PAGE_SIZE - 1) >> CO_ARCH_PAGE_SHIFT; cmon->core_end = cmon->core_vaddr + (cmon->core_pages << CO_ARCH_PAGE_SHIFT); cmon->import = params->import; cmon->config = params->config; cmon->info = params->info; cmon->arch_info = params->arch_info; if (cmon->config.ram_size == 0) { /* Use default RAM sizes */ /* * FIXME: Be careful with that. We don't want to exhaust the host OS's memory * pools because it can destablized it. * * We need to find the minimum requirement for size of the coLinux RAM * for achieving the best performance assuming that the host OS is * caching away the coLinux swap device into the host system's other * RAM. */ if (cmon->manager->hostmem_amount >= 128*1024*1024) { /* Use quarter */ cmon->memory_size = cmon->manager->hostmem_amount/(1024*1024*4); } else { cmon->memory_size = 16; } } else { cmon->memory_size = cmon->config.ram_size; } co_debug("configured to %ld MB", cmon->memory_size); if (cmon->memory_size < 8) cmon->memory_size = 8; else if (cmon->memory_size > 1000) /* 1000 = 1024 - 8*4 */ cmon->memory_size = 1000; /* 24MB = 8 Pages a 4K reserved */ co_debug("after adjustments: %ld MB", cmon->memory_size); cmon->memory_size <<= 20; /* Megify */ if (cmon->manager->hostmem_used + cmon->memory_size > cmon->manager->hostmem_usage_limit) { rc = CO_RC(HOSTMEM_USE_LIMIT_REACHED); params->actual_memsize_used = cmon->memory_size; goto out_free_os_dep; } cmon->manager->hostmem_used += cmon->memory_size; cmon->physical_frames = cmon->memory_size >> CO_ARCH_PAGE_SHIFT; cmon->end_physical = CO_ARCH_KERNEL_OFFSET + cmon->memory_size; cmon->passage_page_vaddr = CO_VPTR_PASSAGE_PAGE; rc = alloc_pp_ram_mapping(cmon); if (!CO_OK(rc)) { goto out_revert_used_mem; } rc = co_os_timer_create(&timer_callback, cmon, 10, &cmon->timer); /* HZ value */ if (!CO_OK(rc)) { co_debug_error("error %08x creating host OS timer", (int)rc); goto out_free_pp; } rc = load_configuration(cmon); if (!CO_OK(rc)) { co_debug_error("error %08x loading monitor configuration", (int)rc); goto out_destroy_timer; } co_os_mutex_acquire(manager->lock); cmon->refcount = 1; manager->monitors_count++; cmon->listed_in_manager = PTRUE; co_list_add_head(&cmon->node, &manager->monitors); co_os_mutex_release(manager->lock); cmon->state = CO_MONITOR_STATE_INITIALIZED; *cmon_out = cmon; return CO_RC(OK);/* error path */out_destroy_timer: co_os_timer_destroy(cmon->timer);out_free_pp: free_pseudo_physical_memory(cmon);out_revert_used_mem: cmon->manager->hostmem_used -= cmon->memory_size;out_free_os_dep: co_monitor_os_exit(cmon);out_free_linux_message_queue: co_queue_flush(&cmon->linux_message_queue);out_free_shared_page: free_shared_page(cmon);out_free_buffer: co_os_free(cmon->io_buffer);out_free_wait: co_os_wait_destroy(cmon->idle_wait);out_free_mutex2: co_os_mutex_destroy(cmon->connected_modules_write_lock);out_free_mutex1: co_os_mutex_destroy(cmon->linux_message_queue_mutex);out_free_console: co_console_destroy(cmon->console);out_free_monitor: co_os_free(cmon);out: return rc;}static co_rc_t co_monitor_destroy(co_monitor_t *cmon, bool_t user_context){ co_manager_t *manager; manager = cmon->manager; co_debug("cleaning up"); co_debug("before free: %ld blocks", cmon->blocks_allocated); if (cmon->state == CO_MONITOR_STATE_RUNNING || cmon->state == CO_MONITOR_STATE_STARTED) { co_os_timer_deactivate(cmon->timer); } if (!user_context) cmon->shared_user_address = NULL; co_monitor_unregister_and_free_block_devices(cmon); co_monitor_unregister_filesystems(cmon); free_pseudo_physical_memory(cmon); manager->hostmem_used -= cmon->memory_size; co_os_free(cmon->io_buffer); free_shared_page(cmon); co_monitor_os_exit(cmon); co_queue_flush(&cmon->linux_message_queue); co_os_timer_destroy(cmon->timer); co_os_mutex_destroy(cmon->connected_modules_write_lock); co_os_mutex_destroy(cmon->linux_message_queue_mutex); co_console_destroy(cmon->console); cmon->console = NULL; co_debug("after free: %ld blocks", cmon->blocks_allocated); co_os_free(cmon); return CO_RC_OK;}static void send_monitor_end_messages(co_monitor_t *cmon){ co_manager_open_desc_t opened; int i; co_os_mutex_acquire(cmon->connected_modules_write_lock); for (i = 0; i < CO_MONITOR_MODULES_COUNT; i++) { opened = cmon->connected_modules[i]; if (!opened) continue; co_manager_send_eof(cmon->manager, opened); cmon->connected_modules[i] = NULL; co_manager_close(cmon->manager, opened); } co_os_mutex_release(cmon->connected_modules_write_lock);}co_rc_t co_monitor_refdown(co_monitor_t *cmon, bool_t user_context, bool_t monitor_owner){ co_manager_t *manager; if (!(cmon->refcount > 0)) return CO_RC(ERROR); manager = cmon->manager; co_os_mutex_acquire(manager->lock); if (monitor_owner && cmon->listed_in_manager) { cmon->listed_in_manager = PFALSE; manager->monitors_count--; co_list_del(&cmon->node); } co_os_mutex_release(manager->lock); if (monitor_owner) send_monitor_end_messages(cmon); if (--cmon->refcount == 0) return co_monitor_destroy(cmon, monitor_owner); return CO_RC(OK);}static co_rc_t co_monitor_user_reset(co_monitor_t *monitor){ co_rc_t rc; monitor->state = CO_MONITOR_STATE_EMPTY; co_os_mutex_acquire(monitor->linux_message_queue_mutex); co_queue_flush(&monitor->linux_message_queue); co_os_mutex_release(monitor->linux_message_queue_mutex); free_pseudo_physical_memory(monitor); rc = alloc_pp_ram_mapping(monitor); if (!CO_OK(rc)) goto out; co_monitor_unregister_and_free_block_devices(monitor); co_monitor_unregister_filesystems(monitor); rc = load_configuration(monitor); if (!CO_OK(rc)) { free_pseudo_physical_memory(monitor); goto out; } co_os_mutex_acquire(monitor->manager->lock); if (!monitor->listed_in_manager) { monitor->listed_in_manager = PTRUE; co_list_add_head(&monitor->node, &monitor->manager->monitors); } co_os_mutex_release(monitor->manager->lock); co_memset(monitor->io_buffer, 0, CO_VPTR_IO_AREA_SIZE); monitor->state = CO_MONITOR_STATE_INITIALIZED; monitor->termination_reason = CO_TERMINATE_END;out: return rc;}static co_rc_t co_monitor_user_get_state(co_monitor_t *monitor, co_monitor_ioctl_get_state_t *params){ params->monitor_state = monitor->state; params->termination_reason = monitor->termination_reason; params->bug_info = monitor->bug_info; return CO_RC(OK);}static co_rc_t co_monitor_user_get_console(co_monitor_t *monitor, co_monitor_ioctl_get_console_t *params){ co_message_t *co_message = NULL; co_console_message_t *message = NULL; unsigned long size; int y; message = NULL; size = (((char *)(&message->putcs + 1)) - ((char *)message)) + (monitor->console->x * sizeof(co_console_cell_t)); params->x = monitor->console->x; params->y = monitor->console->y; co_message = co_os_malloc(size + sizeof(*co_message)); if (!co_message) return CO_RC(OUT_OF_MEMORY); message = (co_console_message_t *)co_message->data; co_message->from = CO_MODULE_LINUX; co_message->to = CO_MODULE_CONSOLE; co_message->priority = CO_PRIORITY_DISCARDABLE; co_message->type = CO_MESSAGE_TYPE_STRING; co_message->size = size; message->type = CO_OPERATION_CONSOLE_PUTCS; message->putcs.x = 0; message->putcs.count = monitor->console->x; for (y=0; y < monitor->console->y; y++) { co_memcpy(&message->putcs.data, &monitor->console->screen[y*monitor->console->x], monitor->console->x * sizeof(unsigned short)); message->putcs.y = y; incoming_message(monitor, co_message); } co_os_free(co_message); return CO_RC(OK);}co_rc_t co_monitor_ioctl(co_monitor_t *cmon, co_manager_ioctl_monitor_t *io_buffer, unsigned long in_size, unsigned long out_size, unsigned long *return_size, co_manager_open_desc_t opened_manager){ co_rc_t rc = CO_RC_ERROR; switch (io_buffer->op) { case CO_MONITOR_IOCTL_CLOSE: { co_monitor_refdown(cmon, PTRUE, opened_manager->monitor_owner); opened_manager->monitor = NULL; opened_manager->monitor_owner = PFALSE; return CO_RC_OK; } case CO_MONITOR_IOCTL_GET_CONSOLE: { co_monitor_ioctl_get_console_t *params; *return_size = sizeof(*params); params = (typeof(params))(io_buffer); return co_monitor_user_get_console(cmon, params); } default: break; } if (!opened_manager->monitor_owner) return rc; switch (io_buffer->op) { case CO_MONITOR_IOCTL_GET_STATE: { co_monitor_ioctl_get_state_t *params; *return_size = sizeof(*params); params = (typeof(params))(io_buffer); return co_monitor_user_get_state(cmon, params); } case CO_MONITOR_IOCTL_RESET: { return co_monitor_user_reset(cmon); } case CO_MONITOR_IOCTL_LOAD_SECTION: { return load_section(cmon, (co_monitor_ioctl_load_section_t *)io_buffer); } case CO_MONITOR_IOCTL_LOAD_INITRD: { return load_initrd(cmon, (co_monitor_ioctl_load_initrd_t *)io_buffer); } case CO_MONITOR_IOCTL_START: { return start(cmon); } case CO_MONITOR_IOCTL_RUN: { return run(cmon, (co_monitor_ioctl_run_t *)io_buffer, out_size, return_size); } default: return rc; } return rc;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -