void thorium_worker_pool_init(struct thorium_worker_pool *pool, int workers, struct thorium_node *node) { pool->debug_mode = 0; pool->node = node; pool->waiting_is_enabled = 0; thorium_balancer_init(&pool->balancer, pool); pool->ticks_without_messages = 0; core_fast_queue_init(&pool->messages_for_triage, sizeof(struct thorium_message)); pool->last_warning = 0; pool->last_scheduling_warning = 0; pool->worker_count = workers; pool->worker_for_run = 0; pool->worker_for_message = 0; /* with only one thread, the main thread * handles everything. */ if (pool->worker_count < 1) { printf("Error: the number of workers must be at least 1.\n"); exit(1); } #ifdef THORIUM_WORKER_POOL_HAS_SPECIAL_QUEUES biosal_work_queue_init(&pool->work_queue); thorium_message_queue_init(&pool->message_queue); #endif /* * Enable the wait/notify algorithm if running on more than * one node. */ if (thorium_node_nodes(pool->node) >= 2) { pool->waiting_is_enabled = 1; } thorium_worker_pool_create_workers(pool); pool->starting_time = time(NULL); core_fast_queue_init(&pool->scheduled_actor_queue_buffer, sizeof(struct thorium_actor *)); core_fast_queue_init(&pool->inbound_message_queue_buffer, sizeof(struct thorium_message)); pool->last_balancing = pool->starting_time; pool->last_signal_check = pool->starting_time; pool->balance_period = THORIUM_SCHEDULER_PERIOD_IN_SECONDS; }
void thorium_worker_pool_start(struct thorium_worker_pool *pool) { int i; int processor; /* start workers * * we start at 1 because the thread 0 is * used by the main thread... */ for (i = 0; i < pool->worker_count; i++) { processor = i; if (thorium_node_nodes(pool->node) != 1) { processor = -1; } thorium_worker_start(thorium_worker_pool_get_worker(pool, i), processor); } }
void thorium_message_multiplexer_init(struct thorium_message_multiplexer *self, struct thorium_node *node, struct thorium_multiplexer_policy *policy) { int size; int i; /* int bytes; */ int position; struct thorium_multiplexed_buffer *multiplexed_buffer; int argc; char **argv; thorium_decision_maker_init(&self->decision_maker); self->policy = policy; self->original_message_count = 0; self->real_message_count = 0; CORE_BITMAP_CLEAR_FLAGS(self->flags); CORE_BITMAP_CLEAR_FLAG(self->flags, FLAG_DISABLED); #ifdef THORIUM_MULTIPLEXER_TRACK_BUFFERS_WITH_CONTENT core_set_init(&self->buffers_with_content, sizeof(int)); #endif core_timer_init(&self->timer); self->buffer_size_in_bytes = thorium_multiplexer_policy_size_threshold(self->policy); #ifdef CONFIG_MULTIPLEXER_USE_DECISION_MAKER self->timeout_in_nanoseconds = thorium_decision_maker_get_best_timeout(&self->decision_maker, THORIUM_TIMEOUT_NO_VALUE); #else self->timeout_in_nanoseconds = self->policy->threshold_time_in_nanoseconds; #endif CORE_DEBUGGER_ASSERT(self->timeout_in_nanoseconds >= 0); self->node = node; core_vector_init(&self->buffers, sizeof(struct thorium_multiplexed_buffer)); size = thorium_node_nodes(self->node); core_vector_resize(&self->buffers, size); /* bytes = size * self->buffer_size_in_bytes; */ #ifdef DEBUG_MULTIPLEXER thorium_printf("DEBUG_MULTIPLEXER size %d bytes %d\n", size, bytes); #endif position = 0; for (i = 0; i < size; ++i) { multiplexed_buffer = core_vector_at(&self->buffers, i); CORE_DEBUGGER_ASSERT(multiplexed_buffer != NULL); /* * Initially, these multiplexed buffers have a NULL buffer. * It is only allocated when needed because each worker is an exporter * of small messages for a subset of all the destination nodes. */ thorium_multiplexed_buffer_init(multiplexed_buffer, self->buffer_size_in_bytes, self->timeout_in_nanoseconds); position += self->buffer_size_in_bytes; #ifdef DEBUG_MULTIPLEXER1 thorium_printf("DEBUG_MULTIPLEXER thorium_message_multiplexer_init index %d buffer %p\n", i, buffer); #endif #ifdef DEBUG_MULTIPLEXER thorium_printf("DEBUG_MULTIPLEXER thorium_message_multiplexer_init (after) index %d buffer %p\n", i, core_vector_at(&self->buffers, i)); #endif } if (thorium_multiplexer_policy_is_disabled(self->policy)) { CORE_BITMAP_SET_FLAG(self->flags, FLAG_DISABLED); } if (thorium_node_nodes(self->node) < thorium_multiplexer_policy_minimum_node_count(self->policy)) { CORE_BITMAP_SET_FLAG(self->flags, FLAG_DISABLED); } self->worker = NULL; argc = node->argc; argv = node->argv; /* * Aside from the policy, the end user can also disable the multiplexer code path */ if (core_command_has_argument(argc, argv, OPTION_DISABLE_MULTIPLEXER)) { CORE_BITMAP_SET_FLAG(self->flags, FLAG_DISABLED); } self->last_send_event_count = 0; self->last_time = core_timer_get_nanoseconds(&self->timer); self->last_update_time = time(NULL); self->degree_of_aggregation_limit = self->policy->degree_of_aggregation_limit; thorium_router_init(&self->router, self->node->nodes, TOPOLOGY_POLYTOPE); if (thorium_node_must_print_data(self->node)) { thorium_router_print(&self->router); } }