void systolic_receive(struct thorium_actor *actor, struct thorium_message *message) { int tag; int name; void *buffer; struct systolic *systolic1; int i; systolic1 = (struct systolic *)thorium_actor_concrete_actor(actor); tag = thorium_message_action(message); name = thorium_actor_name(actor); buffer = thorium_message_buffer(message); if (tag == ACTION_START) { core_vector_unpack(&systolic1->initial_data, buffer); printf("Hello world ! my name is actor:%d and I have %d acquaintances:", name, (int)core_vector_size(&systolic1->initial_data)); for (i = 0; i < core_vector_size(&systolic1->initial_data); i++) { printf(" actor:%d", core_vector_at_as_int(&systolic1->initial_data, i)); } printf("\n"); thorium_actor_send_to_self_empty(actor, ACTION_STOP); } }
void biosal_input_stream_set_offset_reply(struct thorium_actor *self, struct thorium_message *message) { struct biosal_input_stream *concrete_self; concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(self); ++concrete_self->finished_parallel_stream_count; #ifdef DEBUG_ISSUE_594 printf("DEBUG biosal_input_stream_set_offset_reply %d/%d\n", concrete_self->finished_parallel_stream_count, 2 * core_vector_size(&concrete_self->parallel_streams)); #endif if (concrete_self->finished_parallel_stream_count == 2 * core_vector_size(&concrete_self->parallel_streams)) { /* * Assign files to input streams */ thorium_actor_add_action(self, ACTION_INPUT_OPEN_REPLY, biosal_input_stream_open_reply); concrete_self->finished_parallel_stream_count = 0; thorium_actor_send_range_buffer(self, &concrete_self->parallel_streams, ACTION_INPUT_OPEN, strlen(concrete_self->file_name) + 1, concrete_self->file_name); printf("DEBUG SEND ACTION_INPUT_OPEN to %d actors with file %s\n", (int)core_vector_size(&concrete_self->parallel_streams), concrete_self->file_name); } }
void biosal_input_stream_spawn_reply(struct thorium_actor *self, struct thorium_message *message) { int stream; struct biosal_input_stream *concrete_self; int i; int size; uint64_t start_offset; uint64_t end_offset; concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(self); thorium_message_unpack_int(message, 0, &stream); core_vector_push_back_int(&concrete_self->parallel_streams, stream); #ifdef DEBUG_ISSUE_594 printf("DEBUG biosal_input_stream_spawn_reply %d/%d\n", (int)core_vector_size(&concrete_self->parallel_streams), (int)core_vector_size(&concrete_self->start_offsets)); #endif if (core_vector_size(&concrete_self->parallel_streams) == core_vector_size(&concrete_self->start_offsets)) { /* Set offsets */ thorium_actor_add_action(self, ACTION_INPUT_STREAM_SET_START_OFFSET_REPLY, biosal_input_stream_set_offset_reply); thorium_actor_add_action(self, ACTION_INPUT_STREAM_SET_END_OFFSET_REPLY, biosal_input_stream_set_offset_reply); concrete_self->finished_parallel_stream_count = 0; size = core_vector_size(&concrete_self->parallel_streams); for (i = 0; i < size; i++) { start_offset = core_vector_at_as_uint64_t(&concrete_self->start_offsets, i); end_offset = core_vector_at_as_uint64_t(&concrete_self->end_offsets, i); stream = core_vector_at_as_int(&concrete_self->parallel_streams, i); #ifdef DEBUG_ISSUE_594 printf("actor %d send ACTION_INPUT_STREAM_SET_START_OFFSET to %d\n", name, stream); printf("actor %d send ACTION_INPUT_STREAM_SET_END_OFFSET to %d\n", name, stream); #endif thorium_actor_send_uint64_t(self, stream, ACTION_INPUT_STREAM_SET_START_OFFSET, start_offset); thorium_actor_send_uint64_t(self, stream, ACTION_INPUT_STREAM_SET_END_OFFSET, end_offset); } } }
void spate_start_reply_builder(struct thorium_actor *self, struct thorium_message *message) { void *buffer; int spawner; struct spate *concrete_self; concrete_self = (struct spate *)thorium_actor_concrete_actor(self); buffer = thorium_message_buffer(message); core_vector_unpack(&concrete_self->graph_stores, buffer); thorium_actor_log(self, "%s/%d has %d graph stores", thorium_actor_script_name(self), thorium_actor_name(self), (int)core_vector_size(&concrete_self->graph_stores)); spawner = thorium_actor_get_spawner(self, &concrete_self->initial_actors); concrete_self->unitig_manager = THORIUM_ACTOR_SPAWNING_IN_PROGRESS; thorium_actor_add_action_with_condition(self, ACTION_SPAWN_REPLY, spate_spawn_reply_unitig_manager, &concrete_self->unitig_manager, THORIUM_ACTOR_SPAWNING_IN_PROGRESS); thorium_actor_send_int(self, spawner, ACTION_SPAWN, SCRIPT_UNITIG_MANAGER); }
void core_vector_print_int(struct core_vector *self) { int64_t i; int64_t size; size = core_vector_size(self); i = 0; /* printf("["); */ while (i < size) { /* if (i > 0) { printf(", "); } */ printf("%d: %d\n", (int)i, core_vector_at_as_int(self, i)); i++; } /* printf("]"); */ }
void biosal_input_command_print(struct biosal_input_command *self, struct biosal_dna_codec *codec) { printf("[===] input command: store_name %d store_first %" PRIu64 " store_last %" PRIu64 "" " entries %d bytes %d\n", self->store_name, self->store_first, self->store_last, (int)core_vector_size(&self->entries), biosal_input_command_pack_size(self, codec)); }
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 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); } }
void thorium_actor_send_range_default(struct thorium_actor *actor, struct core_vector *actors, int first, int last, struct thorium_message *message) { int use_binomial_tree; struct core_vector destinations; struct core_memory_pool *ephemeral_memory; int name; int action; action = thorium_message_action(message); use_binomial_tree = 0; #ifdef USE_BINOMIAL_TREE /* * ACTION_ASK_TO_STOP basically kills actors (if they agree to). * It is a bad idea to use a binomial tree to send this death signal * since intermediate actors can die before acting as relays. */ if (action != ACTION_ASK_TO_STOP) use_binomial_tree = 1; #endif if (!use_binomial_tree) { thorium_actor_send_range_loop(actor, actors, first, last, message); return; } tracepoint(thorium_binomial_tree, send_range, message, (int)core_vector_size(actors)); /* * Otherwise, use the binomial tree code path. This algorithm is better since it distributed * the sending operations intot a binomial tree where there are a lot of intermediate * actors (to be exact, the number of intermediate actors is close to log2(actors.size)). */ ephemeral_memory = thorium_actor_get_ephemeral_memory(actor); core_vector_init(&destinations, sizeof(int)); core_vector_set_memory_pool(&destinations, ephemeral_memory); CORE_DEBUGGER_ASSERT(core_vector_empty(&destinations)); core_vector_copy_range(actors, first, last, &destinations); /* * Set the source now. */ name = thorium_actor_name(actor); thorium_message_set_source(message, name); thorium_actor_send_range_binomial_tree(actor, &destinations, message); core_vector_destroy(&destinations); }
void spate_set_consumers_reply(struct thorium_actor *self, struct thorium_message *message) { struct spate *concrete_self; concrete_self = (struct spate *)thorium_actor_concrete_actor(self); thorium_actor_log(self, "spate %d sends %d spawners to controller %d", thorium_actor_name(self), (int)core_vector_size(&concrete_self->initial_actors), concrete_self->input_controller); thorium_actor_send_reply_vector(self, ACTION_START, &concrete_self->initial_actors); }
void process_notify(struct thorium_actor *self, struct thorium_message *message) { struct process *concrete_self; concrete_self = (struct process *)thorium_actor_concrete_actor(self); ++concrete_self->ready; if (concrete_self->ready == core_vector_size(&concrete_self->actors)) { thorium_actor_send_range_empty(self, &concrete_self->actors, ACTION_ASK_TO_STOP); } }
void core_vector_sort(struct core_vector *self, core_compare_fn_t compare) { void *saved_pivot_value; int element_size; element_size = core_vector_element_size(self); saved_pivot_value = core_memory_allocate(element_size, MEMORY_VECTOR_HELPER); core_vector_quicksort(self, 0, core_vector_size(self) - 1, compare, saved_pivot_value); core_memory_free(saved_pivot_value, MEMORY_VECTOR_HELPER); }
void test_allocator(struct core_memory_pool *memory) { int i; int size; void *pointer; struct core_vector vector; struct core_timer timer; uint64_t elapsed; i = 1000000; size = 45; core_vector_init(&vector, sizeof(void *)); core_timer_init(&timer); core_timer_start(&timer); while (i--) { if (memory != NULL) { pointer = core_memory_pool_allocate(memory, size); } else { pointer = core_memory_allocate(size, -1); } core_vector_push_back(&vector, &pointer); } core_timer_stop(&timer); elapsed = core_timer_get_elapsed_nanoseconds(&timer); if (memory == NULL) { printf("Not using memory pool... "); } else { printf("Using memory pool... "); } printf("Elapsed : %" PRIu64 " milliseconds\n", elapsed / 1000 / 1000); size = core_vector_size(&vector); for (i = 0; i < size; ++i) { pointer = core_vector_at_as_void_pointer(&vector, i); if (memory != NULL) { core_memory_pool_free(memory, pointer); } else { core_memory_free(pointer, -1); } } core_vector_destroy(&vector); core_timer_destroy(&timer); }
void framr_start(actor_t *actor, message_t *message) { int name; int rank; int size; int neighbor_rank; int neighbor_name; void * buffer; framr_t *self; struct core_vector *spawners; framr_process_args(actor); self = thorium_actor_concrete_actor(actor); name = thorium_actor_name(actor); buffer = thorium_message_buffer(message); spawners = &self->spawners; size = core_vector_size(spawners); pm("received ACTION_START\n"); core_vector_unpack(spawners, buffer); size = core_vector_size(spawners); rank = core_vector_index_of(spawners, &name); neighbor_rank = (rank + 1) % size; neighbor_name = core_vector_at_as_int(spawners, neighbor_rank); pm("Spawner world size = %d\n", size); pm("Spawner %d about to send hello to neighbor %d\n", rank, neighbor_rank); thorium_actor_send_empty(actor, neighbor_name, ACTION_FRAMR_HELLO); /* thorium_message_init(&new_message, ACTION_FRAMR_HELLO, 0, NULL); */ /* thorium_actor_send(actor, neighbor_name, &new_message); */ /* thorium_message_destroy(&new_message); */ }
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); } }
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; }
static void source_send_ping(struct thorium_actor *self) { int target; struct source *concrete_self; concrete_self = thorium_actor_concrete_actor(self); CORE_DEBUGGER_ASSERT(!core_vector_empty(&concrete_self->targets)); if (concrete_self->target == -1) concrete_self->target = thorium_actor_get_random_number(self) % core_vector_size(&concrete_self->targets); target = concrete_self->target; ++concrete_self->target; concrete_self->target %= core_vector_size(&concrete_self->targets); target = core_vector_at_as_int(&concrete_self->targets, target); /* printf("%d sends ACTION_PING to %d\n", thorium_actor_name(self), target); */ thorium_actor_send_empty(self, target, ACTION_PING); }
void thorium_actor_send_range(struct thorium_actor *actor, struct core_vector *actors, struct thorium_message *message) { int first; int last; first = 0; last = core_vector_size(actors) - 1; /* int real_source; real_source = thorium_actor_name(actor); */ thorium_actor_send_range_default(actor, actors, first, last, message); }
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_verify_requests(struct thorium_actor *self, struct thorium_message *message) { struct biosal_input_controller *concrete_actor; int i; int active; active = 0; concrete_actor = (struct biosal_input_controller *)thorium_actor_concrete_actor(self); for (i = 0; i < core_vector_size(&concrete_actor->consumer_active_requests); i++) { if (core_vector_at_as_int(&concrete_actor->consumer_active_requests, i) != 0) { active++; } } if (active == 0) { } }
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 framr_notify(actor_t *actor, message_t *message) { int size; framr_t *self; struct core_vector *spawners; self = thorium_actor_concrete_actor(actor); spawners = &self->spawners; size = core_vector_size(spawners); pm("Boss received NOTIFY\n"); ++self->completed; if (self->completed == size) { thorium_actor_send_range_empty(actor, spawners, ACTION_ASK_TO_STOP); } }
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 process_send_ping(struct thorium_actor *self) { struct process *concrete_self; int destination; int size; int index; int buffer_size; int range; uint64_t checksum; int count; char *buffer; int i; uint64_t *bucket; concrete_self = thorium_actor_concrete_actor(self); range = concrete_self->maximum_buffer_size - concrete_self->minimum_buffer_size; buffer_size = rand() % range; buffer_size += concrete_self->minimum_buffer_size; count = buffer_size + sizeof(checksum); buffer = thorium_actor_allocate(self, count); /* * Generate content; */ for (i = 0; i < buffer_size; ++i) { buffer[i] = i % 256; } checksum = core_hash_data_uint64_t(buffer, buffer_size, SEED); bucket = (uint64_t *)(buffer + buffer_size); *bucket = checksum; size = core_vector_size(&concrete_self->actors); index = rand() % size; destination = core_vector_at_as_int(&concrete_self->actors, index); thorium_actor_send_buffer(self, destination, ACTION_PING, count, buffer); ++concrete_self->active_messages; }
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 spate_start_reply_manager(struct thorium_actor *self, struct thorium_message *message) { struct core_vector consumers; struct spate *concrete_self; void *buffer; concrete_self = (struct spate *)thorium_actor_concrete_actor(self); core_vector_init(&consumers, sizeof(int)); buffer = thorium_message_buffer(message); core_vector_unpack(&consumers, buffer); thorium_actor_log(self, "spate %d sends the names of %d consumers to controller %d", thorium_actor_name(self), (int)core_vector_size(&consumers), concrete_self->input_controller); thorium_actor_send_vector(self, concrete_self->input_controller, ACTION_SET_CONSUMERS, &consumers); core_vector_push_back_vector(&concrete_self->sequence_stores, &consumers); core_vector_destroy(&consumers); }
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_push_back_vector(struct core_vector *self, struct core_vector *other_vector) { core_vector_copy_range(other_vector, 0, core_vector_size(other_vector) - 1, self); }
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); } } }