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 frame_receive(struct thorium_actor *actor, struct thorium_message *message) { int tag; int name; void *buffer; struct frame *concrete_actor; int other; struct core_vector initial_actors; struct core_vector *acquaintance_vector; int source; source = thorium_message_source(message); concrete_actor = (struct frame *)thorium_actor_concrete_actor(actor); tag = thorium_message_action(message); name = thorium_actor_name(actor); buffer = thorium_message_buffer(message); acquaintance_vector = &concrete_actor->acquaintance_vector; if (tag == ACTION_START) { core_vector_init(&initial_actors, sizeof(int)); core_vector_unpack(&initial_actors, buffer); core_vector_push_back_vector(acquaintance_vector, &initial_actors); core_vector_destroy(&initial_actors); other = thorium_actor_spawn(actor, thorium_actor_script(actor)); core_vector_push_back_int(acquaintance_vector, other); thorium_actor_send_empty(actor, other, ACTION_PING); printf("actor %d sends ACTION_PING to new actor %d\n", name, other); } else if (tag == ACTION_PING) { /* new acquaintance */ core_vector_push_back(acquaintance_vector, &source); printf("actor %d (value %d) receives ACTION_PING from actor %d\n", name, concrete_actor->value, source); printf("Acquaintances of actor %d: ", name); core_vector_print_int(acquaintance_vector); printf("\n"); thorium_actor_send_reply_empty(actor, ACTION_PING_REPLY); } else if (tag == ACTION_PING_REPLY) { concrete_actor->pings++; printf("actor %d receives ACTION_PING_REPLY from actor %d\n", name, source); /* kill the system */ if (concrete_actor->migrated_other && concrete_actor->pings == 2) { thorium_actor_send_reply_empty(actor, ACTION_ASK_TO_STOP); thorium_actor_send_to_self_empty(actor, ACTION_ASK_TO_STOP); return; } /* migrate other actor */ printf("actor %d asks actor %d to migrate using actor %d as spawner\n", name, source, name); printf("Acquaintances of actor %d: ", name); core_vector_print_int(acquaintance_vector); printf("\n"); thorium_actor_send_reply_int(actor, ACTION_MIGRATE, name); /* send a message to other while it is migrating. * this is supposed to work ! */ printf("actor %d sends ACTION_PING to %d while it is migrating\n", name, source); thorium_actor_send_reply_empty(actor, ACTION_PING); concrete_actor->migrated_other = 1; } else if (tag == ACTION_MIGRATE_REPLY) { thorium_message_unpack_int(message, 0, &other); printf("actor %d received migrated actor %d\n", name, other); printf("Acquaintances of actor %d: ", name); core_vector_print_int(acquaintance_vector); printf("\n"); /* it is possible that the ACTION_PING went through * before the migration */ if (concrete_actor->pings == 2) { thorium_actor_send_reply_empty(actor, ACTION_ASK_TO_STOP); thorium_actor_send_to_self_empty(actor, ACTION_ASK_TO_STOP); } } else if (tag == ACTION_PACK) { thorium_actor_send_reply_int(actor, ACTION_PACK_REPLY, concrete_actor->value); } else if (tag == ACTION_UNPACK) { thorium_message_unpack_int(message, 0, &concrete_actor->value); thorium_actor_send_reply_empty(actor, ACTION_UNPACK_REPLY); } else if (tag == ACTION_ASK_TO_STOP) { printf("actor %d received ACTION_ASK_TO_STOP, value: %d ", name, concrete_actor->value); printf("acquaintance vector: "); core_vector_print_int(acquaintance_vector); printf("\n"); thorium_actor_send_to_self_empty(actor, ACTION_STOP); } }
void biosal_input_stream_count_reply(struct thorium_actor *self, struct thorium_message *message) { struct biosal_input_stream *concrete_self; void *buffer; uint64_t result; struct biosal_mega_block *block; int i; int size; struct core_vector *vector; int source_index; int source; int j; uint64_t total; concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(self); buffer = thorium_message_buffer(message); source = thorium_message_source(message); source_index = core_vector_index_of(&concrete_self->parallel_streams, &source); vector = core_vector_at(&concrete_self->parallel_mega_blocks, source_index); core_vector_unpack(vector, buffer); block = core_vector_at_last(vector); result = biosal_mega_block_get_entries(block); concrete_self->total_entries += result; ++concrete_self->finished_parallel_stream_count; printf("DEBUG count_reply %d/%d\n", concrete_self->finished_parallel_stream_count, (int)core_vector_size(&concrete_self->parallel_streams)); /* * Send back an array of mega blocks when it is done. */ if (concrete_self->finished_parallel_stream_count == core_vector_size(&concrete_self->parallel_streams)) { /* * Transfer mega blocks * to main vector. */ size = core_vector_size(&concrete_self->parallel_streams); for (i = 0; i < size; i++) { /* * This is easy to do because they are already sorted. * * With one parallel stream, there is nothing else to do. * * Otherwise, mega blocks with correct entries_from_start * need to be created (the entries fields are only for * the stuff between 2 offsets so they are already * correct. */ vector = core_vector_at(&concrete_self->parallel_mega_blocks, i); #if 0 printf("ParallelStream %d\n", i); #endif for (j = 0; j < core_vector_size(vector); j++) { block = core_vector_at(vector, j); biosal_mega_block_print(block); } core_vector_push_back_vector(&concrete_self->mega_blocks, vector); } /* * Update total */ total = 0; for (i = 0; i < core_vector_size(&concrete_self->mega_blocks); i++) { block = core_vector_at(&concrete_self->mega_blocks, i); total += biosal_mega_block_get_entries(block); biosal_mega_block_set_entries_from_start(block, total); } /* * Destroy mega block vectors. */ for (i = 0; i < size; i++) { vector = core_vector_at(&concrete_self->parallel_mega_blocks, i); core_vector_destroy(vector); } core_vector_resize(&concrete_self->parallel_mega_blocks, 0); printf("DEBUG send ACTION_INPUT_COUNT_IN_PARALLEL_REPLY to %d\n", concrete_self->controller); thorium_actor_send_vector(self, concrete_self->controller, ACTION_INPUT_COUNT_IN_PARALLEL_REPLY, &concrete_self->mega_blocks); } }
void core_vector_init_copy(struct core_vector *self, struct core_vector *other) { core_vector_init(self, core_vector_element_size(other)); core_vector_push_back_vector(self, other); }