void core_vector_swap(struct core_vector *self, int64_t index1, int64_t index2) { void *value1; void *value2; int i; char saved; int element_size; value1 = core_vector_at(self, index1); value2 = core_vector_at(self, index2); if (value1 == NULL || value2 == NULL) { return; } element_size = core_vector_element_size(self); /* swap 2 elements, byte by byte. */ for (i = 0; i < element_size; i++) { saved = ((char *)value1)[i]; ((char *)value1)[i] = ((char *)value2)[i]; ((char *)value2)[i] = saved; } }
int64_t core_vector_select_pivot(struct core_vector *self, int64_t first, int64_t last, core_compare_fn_t compare) { int64_t middle; void *first_value; void *last_value; void *middle_value; middle = first + (last - first) / 2; first_value = core_vector_at(self, first); last_value = core_vector_at(self, last); middle_value = core_vector_at(self, middle); if (compare(first_value, middle_value) <= 0 && compare(middle_value, last_value) <= 0) { return middle; } else if (compare(middle_value, first_value) <= 0 && compare(first_value, last_value) <= 0) { return first; } return last; }
/** * \see http://en.wikipedia.org/wiki/Quicksort */ int64_t core_vector_partition(struct core_vector *self, int64_t first, int64_t last, core_compare_fn_t compare, void *saved_pivot_value) { int64_t pivot_index; void *pivot_value; int64_t store_index; void *other_value; int64_t i; int element_size; pivot_index = core_vector_select_pivot(self, first, last, compare); pivot_value = core_vector_at(self, pivot_index); element_size = core_vector_element_size(self); core_memory_copy(saved_pivot_value, pivot_value, element_size); #ifdef CORE_VECTOR_HELPER_DEBUG printf("DEBUG ENTER partition first %d last %d pivot_index %d pivot_value %d ", (int)first, (int)last, (int)pivot_index, *(int *)pivot_value); core_vector_print_int(self); printf("\n"); #endif #ifdef CORE_VECTOR_HELPER_DEBUG printf("pivot_index %d pivot_value %d\n", pivot_index, *(int *)pivot_value); #endif core_vector_swap(self, pivot_index, last); store_index = first; for (i = first; i <= last - 1; i++) { other_value = core_vector_at(self, i); if (compare(other_value, saved_pivot_value) <= 0) { core_vector_swap(self, i, store_index); store_index = store_index + 1; } } core_vector_swap(self, store_index, last); pivot_index = store_index; #ifdef CORE_VECTOR_HELPER_DEBUG printf("DEBUG EXIT partition first %d last %d pivot_index %d pivot_value %d ", (int)first, (int)last, (int)pivot_index, *(int *)pivot_value); core_vector_print_int(self); printf("\n"); #endif return pivot_index; }
void core_vector_set(struct core_vector *self, int64_t index, void *data) { void *bucket; bucket = core_vector_at(self, index); core_memory_copy(bucket, data, self->element_size); }
void biosal_input_controller_get_node_worker_count_reply(struct thorium_actor *actor, struct thorium_message *message) { int tag; int source; void *buffer; int count; int index; struct biosal_input_controller *concrete_actor; int spawner; int worker_count; int *bucket; concrete_actor = (struct biosal_input_controller *)thorium_actor_concrete_actor(actor); thorium_message_get_all(message, &tag, &count, &buffer, &source); spawner = source; thorium_message_unpack_int(message, 0, &worker_count); index = core_vector_index_of(&concrete_actor->spawners, &spawner); bucket = core_vector_at(&concrete_actor->stores_per_spawner, index); *bucket = worker_count * concrete_actor->stores_per_worker_per_spawner; printf("DEBUG spawner %d (node %d) is on a node that has %d workers\n", spawner, index, worker_count); thorium_actor_send_to_self_empty(actor, ACTION_INPUT_CONTROLLER_CREATE_STORES); }
void thorium_actor_send_range_loop(struct thorium_actor *actor, struct core_vector *actors, int first, int last, struct thorium_message *message) { int i; int the_actor; #ifdef THORIUM_ACTOR_DEBUG1 printf("DEBUG thorium_actor_send_range_default%i-%i\n", first, last); #endif i = first; while (i <= last) { #ifdef THORIUM_ACTOR_DEBUG_20140601_1 printf("DEBUG sending %d to %d\n", thorium_message_action(message), i); #endif the_actor = *(int *)core_vector_at(actors, i); #ifdef DEBUG_BINOMIAL_TREE printf("send_range_loop, sending to %d\n", the_actor); thorium_message_print(message); #endif thorium_actor_send(actor, the_actor, message); i++; } }
void biosal_assembly_arc_classifier_verify_counters(struct thorium_actor *self) { struct biosal_assembly_arc_classifier *concrete_self; concrete_self = (struct biosal_assembly_arc_classifier *)thorium_actor_concrete_actor(self); #if 0 size = core_vector_size(&concrete_self->consumers); #endif /* * Don't do anything if the producer is not waiting anyway. */ if (!concrete_self->producer_is_waiting) { return; } if (concrete_self->consumer_count_above_threshold > 0) { return; } /* * Make sure that we have enough memory available. * This verification is not performed if there are 0 active * requests. */ /* * The code here is to make sure that there is enough memory. */ if (concrete_self->active_requests > 0 && !core_memory_has_enough_bytes()) { return; } #if 0 /* * Abort if at least one counter is above the threshold. */ for (i = 0; i < size; i++) { bucket = core_vector_at(&concrete_self->pending_requests, i); active_count = *bucket; if (active_count > concrete_self->maximum_pending_request_count) { return; } } #endif /* * Trigger an actor event now. */ thorium_actor_send_empty(self, concrete_self->source, ACTION_ASSEMBLY_PUSH_ARC_BLOCK_REPLY); concrete_self->producer_is_waiting = 0; }
void core_vector_copy_range(struct core_vector *self, int64_t first, int64_t last, struct core_vector *destination) { int64_t i; for (i = first; i <= last; i++) { core_vector_push_back(destination, core_vector_at(self, i)); } }
void biosal_input_controller_receive_store_entry_counts(struct thorium_actor *actor, struct thorium_message *message) { struct biosal_input_controller *concrete_actor; struct core_vector store_entries; void *buffer; int i; int store; uint64_t entries; struct thorium_message new_message; int name; core_vector_init(&store_entries, sizeof(uint64_t)); concrete_actor = (struct biosal_input_controller *)thorium_actor_concrete_actor(actor); buffer = thorium_message_buffer(message); name = thorium_actor_name(actor); concrete_actor->ready_consumers = 0; #ifdef BIOSAL_INPUT_CONTROLLER_DEBUG printf("DEBUG biosal_input_controller_receive_store_entry_counts unpacking entries\n"); #endif core_vector_init(&store_entries, 0); core_vector_unpack(&store_entries, buffer); for (i = 0; i < core_vector_size(&store_entries); i++) { store = *(int *)core_vector_at(&concrete_actor->consumers, i); entries = *(uint64_t *)core_vector_at(&store_entries, i); printf("DEBUG controller/%d tells consumer/%d to reserve %" PRIu64 " buckets\n", name, store, entries); thorium_message_init(&new_message, ACTION_RESERVE, sizeof(entries), &entries); thorium_actor_send(actor, store, &new_message); } #ifdef BIOSAL_INPUT_CONTROLLER_DEBUG printf("DEBUG biosal_input_controller_receive_store_entry_counts will wait for replies\n"); #endif core_vector_destroy(&store_entries); }
void biosal_assembly_arc_classifier_receive(struct thorium_actor *self, struct thorium_message *message) { int tag; void *buffer; struct biosal_assembly_arc_classifier *concrete_self; int size; int i; int *bucket; int source; int source_index; if (thorium_actor_take_action(self, message)) { return; } concrete_self = (struct biosal_assembly_arc_classifier *)thorium_actor_concrete_actor(self); tag = thorium_message_action(message); buffer = thorium_message_buffer(message); source = thorium_message_source(message); if (tag == ACTION_SET_CONSUMERS) { core_vector_unpack(&concrete_self->consumers, buffer); size = core_vector_size(&concrete_self->consumers); core_vector_resize(&concrete_self->pending_requests, size); for (i = 0; i < size; i++) { core_vector_set_int(&concrete_self->pending_requests, i, 0); } thorium_actor_send_reply_empty(self, ACTION_SET_CONSUMERS_REPLY); } else if (tag == ACTION_ASSEMBLY_PUSH_ARC_BLOCK_REPLY){ /* * Decrease counter now. */ source_index = core_vector_index_of(&concrete_self->consumers, &source); bucket = core_vector_at(&concrete_self->pending_requests, source_index); --(*bucket); --concrete_self->active_requests; /* * The previous value was maximum_pending_request_count + 1 */ if (*bucket == concrete_self->maximum_pending_request_count) { --concrete_self->consumer_count_above_threshold; } biosal_assembly_arc_classifier_verify_counters(self); } }
struct thorium_worker *thorium_worker_pool_select_worker_for_message_round_robin(struct thorium_worker_pool *self) { struct thorium_worker *worker; worker = core_vector_at(&self->worker_array, self->worker_for_message); ++self->worker_for_message; if (self->worker_for_message == self->worker_count) self->worker_for_message = 0; return worker; }
void *core_vector_at_as_void_pointer(struct core_vector *self, int64_t index) { void **bucket; bucket = (void **)core_vector_at(self, index); if (bucket == NULL) { return NULL; } return *bucket; }
float core_vector_at_as_float(struct core_vector *self, int64_t index) { float *bucket; bucket = (float *)core_vector_at(self, index); if (bucket == NULL) { return -1; } return *bucket; }
char core_vector_at_as_char(struct core_vector *self, int64_t index) { char *bucket; bucket = NULL; bucket = (char *)core_vector_at(self, index); if (bucket == NULL) { return -1; } return *bucket; }
/* #define CORE_VECTOR_HELPER_DEBUG */ int core_vector_at_as_int(struct core_vector *self, int64_t index) { int *bucket; bucket = NULL; bucket = (int *)core_vector_at(self, index); if (bucket != NULL) { return *bucket; } return -1; }
uint64_t core_vector_at_as_uint64_t(struct core_vector *self, int64_t index) { uint64_t *bucket; bucket = NULL; bucket = (uint64_t *)core_vector_at(self, index); if (bucket == NULL) { return 0; } return *bucket; }
void biosal_input_controller_set_offset_reply(struct thorium_actor *self, struct thorium_message *message) { int stream_index; int acquaintance_index; int source; int block_index; struct biosal_mega_block *block; struct biosal_input_controller *concrete_actor; int file_index; char *file_name; struct thorium_message new_message; source = thorium_message_source(message); acquaintance_index = source; concrete_actor = (struct biosal_input_controller *)thorium_actor_concrete_actor(self); stream_index = core_vector_index_of(&concrete_actor->reading_streams, &acquaintance_index); block_index = core_map_get_int(&concrete_actor->assigned_blocks, &stream_index); #ifdef BIOSAL_INPUT_CONTROLLER_DEBUG_READING_STREAMS printf("DEBUG got reply from stream/%d for offset, stream_index %d block_index %d\n", source, stream_index, block_index); #endif block = (struct biosal_mega_block *)core_vector_at(&concrete_actor->mega_block_vector, block_index); file_index = biosal_mega_block_get_file(block); file_name = *(char **)core_vector_at(&concrete_actor->files, file_index); printf("DEBUG send ACTION_INPUT_OPEN %s\n", file_name); thorium_message_init(&new_message, ACTION_INPUT_OPEN, strlen(file_name) + 1, file_name); thorium_actor_send_reply(self, &new_message); thorium_message_destroy(&new_message); }
void thorium_worker_pool_create_workers(struct thorium_worker_pool *pool) { int i; struct thorium_worker *worker; if (pool->worker_count <= 0) { return; } core_vector_init(&pool->worker_array, sizeof(struct thorium_worker)); #ifdef THORIUM_WORKER_POOL_USE_COUNT_CACHE core_vector_init(&pool->message_count_cache, sizeof(int)); #endif core_vector_resize(&pool->worker_array, pool->worker_count); #ifdef THORIUM_WORKER_POOL_USE_COUNT_CACHE core_vector_resize(&pool->message_count_cache, pool->worker_count); #endif pool->worker_cache = (struct thorium_worker *)core_vector_at(&pool->worker_array, 0); #ifdef THORIUM_WORKER_POOL_USE_COUNT_CACHE pool->message_cache = (int *)core_vector_at(&pool->message_count_cache, 0); #endif for (i = 0; i < pool->worker_count; i++) { worker = thorium_worker_pool_get_worker(pool, i); thorium_worker_init(worker, i, pool->node); if (pool->waiting_is_enabled) { thorium_worker_enable_waiting(worker); } #ifdef THORIUM_WORKER_POOL_USE_COUNT_CACHE core_vector_set_int(&pool->message_count_cache, i, 0); #endif } }
int core_vector_get_value(struct core_vector *self, int64_t index, void *value) { void *bucket; bucket = core_vector_at(self, index); if (bucket == NULL) { return 0; } core_memory_copy(value, bucket, self->element_size); return 1; }
int64_t core_vector_index_of(struct core_vector *self, void *data) { int64_t i; int64_t last; last = core_vector_size(self) - 1; for (i = 0; i <= last; i++) { if (memcmp(core_vector_at(self, i), data, self->element_size) == 0) { return i; } } return -1; }
void core_vector_update(struct core_vector *self, void *old_item, void *new_item) { int64_t i; int64_t last; void *bucket; last = core_vector_size(self) - 1; for (i = 0; i <= last; i++) { bucket = core_vector_at(self, i); if (memcmp(bucket, old_item, self->element_size) == 0) { core_vector_set(self, i, new_item); } } }
void biosal_input_controller_destroy(struct thorium_actor *actor) { struct biosal_input_controller *concrete_actor; int i; char *pointer; struct core_map_iterator iterator; struct core_vector *vector; concrete_actor = (struct biosal_input_controller *)thorium_actor_concrete_actor(actor); core_timer_destroy(&concrete_actor->input_timer); core_timer_destroy(&concrete_actor->counting_timer); core_timer_destroy(&concrete_actor->distribution_timer); biosal_dna_codec_destroy(&concrete_actor->codec); for (i = 0; i < core_vector_size(&concrete_actor->files); i++) { pointer = *(char **)core_vector_at(&concrete_actor->files, i); core_memory_free(pointer, MEMORY_CONTROLLER); } core_vector_destroy(&concrete_actor->mega_block_vector); core_vector_destroy(&concrete_actor->counting_streams); core_vector_destroy(&concrete_actor->reading_streams); core_vector_destroy(&concrete_actor->partition_commands); core_vector_destroy(&concrete_actor->consumer_active_requests); core_vector_destroy(&concrete_actor->stream_consumers); core_vector_destroy(&concrete_actor->files); core_vector_destroy(&concrete_actor->spawners); core_vector_destroy(&concrete_actor->counts); core_vector_destroy(&concrete_actor->consumers); core_vector_destroy(&concrete_actor->stores_per_spawner); core_queue_destroy(&concrete_actor->unprepared_spawners); core_map_iterator_init(&iterator, &concrete_actor->mega_blocks); while (core_map_iterator_has_next(&iterator)) { core_map_iterator_next(&iterator, NULL, (void **)&vector); core_vector_destroy(vector); } core_map_iterator_destroy(&iterator); core_map_destroy(&concrete_actor->mega_blocks); core_map_destroy(&concrete_actor->assigned_blocks); }
void thorium_message_multiplexer_print_traffic_reduction(struct thorium_message_multiplexer *self) { char buffer[1024]; int position; int i; int size; struct thorium_multiplexed_buffer *multiplexed_buffer; int original_message_count; int real_message_count; float reduction; position = 0; position += sprintf(buffer + position, "[thorium] node %d worker %d multiplexer channels", thorium_node_name(self->node), thorium_worker_name(self->worker)); size = core_vector_size(&self->buffers); for (i = 0; i < size; ++i) { multiplexed_buffer = core_vector_at(&self->buffers, i); original_message_count = thorium_multiplexed_buffer_original_message_count(multiplexed_buffer); real_message_count = thorium_multiplexed_buffer_real_message_count(multiplexed_buffer); if (original_message_count == 0) continue; reduction = (0.0 + original_message_count - real_message_count) / original_message_count; reduction *= 100.0; position += sprintf(buffer + position, " [%d: %d %d %.2f%%]", i, original_message_count, real_message_count, reduction); } position += sprintf(buffer + position, "\n"); thorium_printf("%s", buffer); }
void biosal_input_stream_open_reply(struct thorium_actor *self, struct thorium_message *message) { struct biosal_input_stream *concrete_self; int i; int size; struct core_vector *vector; concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(self); ++concrete_self->finished_parallel_stream_count; #if 0 printf("DEBUG open_reply\n"); #endif if (concrete_self->finished_parallel_stream_count == core_vector_size(&concrete_self->parallel_streams)) { concrete_self->finished_parallel_stream_count = 0; size = core_vector_size(&concrete_self->parallel_streams); core_vector_resize(&concrete_self->parallel_mega_blocks, size); for (i = 0; i < size; i++) { vector = core_vector_at(&concrete_self->parallel_mega_blocks, i); core_vector_init(vector, sizeof(struct biosal_mega_block)); } thorium_actor_send_range_empty(self, &concrete_self->parallel_streams, ACTION_INPUT_COUNT); } }
void core_vector_push_back(struct core_vector *self, void *data) { int64_t index; int64_t new_maximum_size; void *bucket; CORE_DEBUGGER_ASSERT(data != NULL); #ifdef CORE_VECTOR_DEBUG printf("DEBUG core_vector_push_back size %d max %d\n", (int)self->size, (int)self->maximum_size); #endif if (self->size + 1 > self->maximum_size) { new_maximum_size = 2 * self->maximum_size; if (new_maximum_size == 0) { new_maximum_size = CORE_VECTOR_INITIAL_BUCKET_COUNT; } core_vector_reserve(self, new_maximum_size); core_vector_push_back(self, data); return; } index = self->size; self->size++; bucket = core_vector_at(self, index); core_memory_copy(bucket, data, self->element_size); #ifdef CORE_VECTOR_DEBUG printf("DEBUG core_vector_push_back new_size is %d, pushed in bucket %d, value in bucket %d\n", self->size, index, *(int *)bucket); #endif }
void biosal_input_controller_add_store(struct thorium_actor *actor, struct thorium_message *message) { int source; int store; int index; struct biosal_input_controller *concrete_actor; int *bucket; /* printf("DEBUG biosal_input_controller_add_store\n"); */ concrete_actor = (struct biosal_input_controller *)thorium_actor_concrete_actor(actor); source = thorium_message_source(message); thorium_message_unpack_int(message, 0, &store); index = core_vector_index_of(&concrete_actor->spawners, &source); /* printf("DEBUG biosal_input_controller_add_store index %d\n", index); */ bucket = core_vector_at(&concrete_actor->stores_per_spawner, index); /* the content of the bucket is initially the total number of * stores that are desired for this spawner. */ *bucket = (*bucket - 1); core_vector_push_back(&concrete_actor->consumers, &store); thorium_actor_send_to_self_empty(actor, ACTION_INPUT_CONTROLLER_CREATE_STORES); /* printf("DEBUG remaining to spawn: %d (before returning)\n", *bucket); */ }
void *core_vector_at_last(struct core_vector *self) { return core_vector_at(self, core_vector_size(self) / 2); }
void *core_vector_at_middle(struct core_vector *self) { return core_vector_at(self, core_vector_size(self) - 1); }
void *core_vector_at_first(struct core_vector *self) { return core_vector_at(self, 0); }
void table_receive(struct thorium_actor *actor, struct thorium_message *message) { int tag; int source; int name; int remote; struct thorium_message spawn_message; int script; int new_actor; void *buffer; struct table *table1; table1 = (struct table *)thorium_actor_concrete_actor(actor); source = thorium_message_source(message); tag = thorium_message_action(message); name = thorium_actor_name(actor); buffer = thorium_message_buffer(message); if (tag == ACTION_START) { printf("Actor %i receives ACTION_START from actor %i\n", name, source); core_vector_init(&table1->spawners, 0); core_vector_unpack(&table1->spawners, buffer); remote = core_vector_index_of(&table1->spawners, &name) + 1; remote %= core_vector_size(&table1->spawners); script = SCRIPT_TABLE; thorium_message_init(&spawn_message, ACTION_SPAWN, sizeof(script), &script); thorium_actor_send(actor, *(int *)core_vector_at(&table1->spawners, remote), &spawn_message); /* printf("sending notification\n"); thorium_message_init(message, ACTION_TABLE_NOTIFY, 0, NULL); thorium_actor_send(actor, 0, message); */ } else if (tag == ACTION_SPAWN_REPLY) { new_actor= *(int *)buffer; printf("Actor %i receives ACTION_SPAWN_REPLY from actor %i," " new actor is %d\n", name, source, new_actor); thorium_message_init(message, ACTION_TABLE_DIE2, 0, NULL); thorium_actor_send(actor, new_actor, message); thorium_message_init(message, ACTION_TABLE_NOTIFY, 0, NULL); thorium_actor_send(actor, core_vector_at_as_int(&table1->spawners, 0), message); } else if (tag == ACTION_TABLE_DIE2) { printf("Actor %i receives ACTION_TABLE_DIE2 from actor %i\n", name, source); if (name < core_vector_size(&table1->spawners)) { return; } thorium_message_init(message, ACTION_STOP, 0, NULL); thorium_actor_send(actor, name, message); } else if (tag == ACTION_TABLE_DIE) { printf("Actor %i receives ACTION_TABLE_DIE from actor %i\n", name, source); thorium_message_init(message, ACTION_STOP, 0, NULL); thorium_actor_send(actor, name, message); } else if (tag == ACTION_TABLE_NOTIFY) { printf("Actor %i receives ACTION_TABLE_NOTIFY from actor %i\n", name, source); table1->done++; if (table1->done == core_vector_size(&table1->spawners)) { printf("actor %d kills %d to %d\n", name, 0, (int)core_vector_size(&table1->spawners) - 1); thorium_message_init(message, ACTION_TABLE_DIE, 0, NULL); thorium_actor_send_range(actor, &table1->spawners, message); } } }