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 reader_receive(struct thorium_actor *actor, struct thorium_message *message) { int tag; int argc; char **argv; /*int i;*/ int name; struct reader *reader1; int source; uint64_t count; void *buffer; int sequences; int script; int sequence_index; char *received_sequence; int error; reader1 = (struct reader *)thorium_actor_concrete_actor(actor); tag = thorium_message_action(message); source = thorium_message_source(message); buffer = thorium_message_buffer(message); name = thorium_actor_name(actor); if (tag == ACTION_START) { core_vector_init(&reader1->spawners, 0); core_vector_unpack(&reader1->spawners, buffer); argc = thorium_actor_argc(actor); argv = thorium_actor_argv(actor); name = thorium_actor_name(actor); reader1->last_report = 0; /* printf("actor %i received %i arguments\n", name, argc); for (i = 0; i < argc ;i++) { printf(" argument %i : %s\n", i, argv[i]); } */ if (core_vector_index_of(&reader1->spawners, &name) != 0) { thorium_message_init(message, ACTION_STOP, 0, NULL); thorium_actor_send(actor, name, message); return; } if (argc == 1) { thorium_message_init(message, ACTION_STOP, 0, NULL); thorium_actor_send(actor, name, message); return; } reader1->sequence_reader = thorium_actor_spawn(actor, SCRIPT_INPUT_STREAM); reader1->file = argv[argc - 1]; thorium_message_init(message, ACTION_INPUT_OPEN, strlen(reader1->file) + 1, reader1->file); printf("actor %i: asking actor %i to count entries in %s\n", name, reader1->sequence_reader, reader1->file); thorium_actor_send(actor, reader1->sequence_reader, message); } else if (tag == ACTION_INPUT_COUNT_PROGRESS) { sequences = *(int64_t *)buffer; if (sequences < reader1->last_report + 10000000) { return; } printf("Actor %i received a progress report from actor %i: %i\n", name, source, sequences); reader1->last_report = sequences; } else if (tag == ACTION_INPUT_OPEN_REPLY && !reader1->counted) { thorium_message_unpack_int(message, 0, &error); if (error == BIOSAL_INPUT_ERROR_NO_ERROR) { printf("Successfully opened file.\n"); thorium_actor_send_reply_empty(actor, ACTION_INPUT_COUNT); } else if (error == BIOSAL_INPUT_ERROR_FILE_NOT_FOUND) { printf("Error, file not found! \n"); thorium_actor_send_to_self_empty(actor, ACTION_STOP); } else if (error == BIOSAL_INPUT_ERROR_FORMAT_NOT_SUPPORTED) { printf("Error, format not supported! \n"); thorium_actor_send_to_self_empty(actor, ACTION_STOP); } } else if (tag == ACTION_INPUT_COUNT_REPLY) { count = *(int64_t*)thorium_message_buffer(message); printf("actor %i: file has %" PRIu64 " items\n", name, count); thorium_message_init(message, ACTION_INPUT_CLOSE, 0, NULL); thorium_actor_send(actor, source, message); reader1->counted = 1; } else if (tag == ACTION_INPUT_CLOSE_REPLY && !reader1->pulled) { /* not necessary, it is already dead. */ thorium_actor_send_reply_empty(actor, ACTION_ASK_TO_STOP); printf("actor %d received ACTION_INPUT_CLOSE_REPLY from actor %d, asking it to stop" " with ACTION_ASK_TO_STOP\n", name, source); /* thorium_message_init(message, ACTION_STOP, 0, NULL); thorium_actor_send(actor, name, message); return; */ script = SCRIPT_INPUT_STREAM; thorium_message_init(message, ACTION_SPAWN, sizeof(script), &script); thorium_actor_send(actor, name, message); } else if (tag == ACTION_INPUT_CLOSE_REPLY && reader1->pulled) { thorium_actor_send_reply_empty(actor, ACTION_ASK_TO_STOP); thorium_actor_send_to_self_empty(actor, ACTION_STOP); } else if (tag == ACTION_ASK_TO_STOP_REPLY && reader1->pulled) { /* this tag will never arrive here */ thorium_message_init(message, ACTION_STOP, 0, NULL); thorium_actor_send(actor, name, message); } else if (tag == ACTION_SPAWN_REPLY && source == name) { reader1->sequence_reader = *(int *)buffer; printf("actor %d tells actor %d to open %s to pull sequences from the file\n", name, reader1->sequence_reader, reader1->file); thorium_message_init(message, ACTION_INPUT_OPEN, strlen(reader1->file) + 1, reader1->file); thorium_actor_send(actor, reader1->sequence_reader, message); } else if (tag == ACTION_INPUT_OPEN_REPLY && reader1->counted) { thorium_message_init(message, ACTION_INPUT_GET_SEQUENCE, 0, NULL); thorium_actor_send(actor, source, message); } else if (tag == ACTION_INPUT_GET_SEQUENCE_REPLY) { sequence_index = *(int *)buffer; received_sequence = (char*)buffer + sizeof(sequence_index); /* printf("DEBUG %d %s\n", sequence_index, received_sequence); */ if (sequence_index == 123456) { printf("actor %d says that sequence %d is %s.\n", name, sequence_index, received_sequence); } else if (sequence_index % 100000 == 0) { printf("actor %d is pulling sequences from fellow local actor %d," " %d sequences pulled so far !\n", name, reader1->sequence_reader, sequence_index); } if (sequence_index < 1000000) { thorium_message_init(message, ACTION_INPUT_GET_SEQUENCE, 0, NULL); thorium_actor_send(actor, source, message); } else { thorium_message_init(message, ACTION_INPUT_CLOSE, 0, NULL); thorium_actor_send(actor, source, message); reader1->pulled = 1; } } else if (tag == ACTION_INPUT_GET_SEQUENCE_END) { printf("actor %d: reached the end...\n", name); thorium_message_init(message, ACTION_INPUT_CLOSE, 0, NULL); thorium_actor_send(actor, source, message); reader1->pulled = 1; } }
void ring_receive(struct thorium_actor *actor, struct thorium_message *message) { int tag; int new_actor; int previous; int name; struct ring *concrete_actor; int messages; int previous_actor; char *buffer; int destination; concrete_actor = (struct ring *)thorium_actor_concrete_actor(actor); tag = thorium_message_action(message); buffer = thorium_message_buffer(message); name = thorium_actor_name(actor); if (tag == ACTION_START) { core_vector_init(&concrete_actor->spawners, 0); core_vector_unpack(&concrete_actor->spawners, buffer); printf("actor %d ACTION_START, %d spawners\n", name, (int)core_vector_size(&concrete_actor->spawners)); destination = *(int *)core_vector_at(&concrete_actor->spawners, 0); thorium_actor_send_empty(actor, destination, ACTION_RING_READY); } else if (tag == ACTION_RING_READY && concrete_actor->step == RING_STEP_RECEIVE_SPAWNERS) { concrete_actor->ready_rings++; if (concrete_actor->ready_rings == (int)core_vector_size(&concrete_actor->spawners)) { thorium_actor_send_range_empty(actor, &concrete_actor->spawners, ACTION_RING_SPAWN); concrete_actor->step = RING_STEP_SPAWN; concrete_actor->ready_rings = 0; } } else if (tag == ACTION_RING_SPAWN) { printf("actor/%d is spawning %d senders\n", thorium_actor_name(actor), concrete_actor->senders); concrete_actor->step = RING_STEP_SPAWN; new_actor = thorium_actor_spawn(actor, SCRIPT_SENDER); concrete_actor->first = new_actor; previous = new_actor; new_actor = thorium_actor_spawn(actor, SCRIPT_SENDER); concrete_actor->previous = new_actor; thorium_message_init(message, ACTION_SENDER_SET_NEXT, sizeof(new_actor), &new_actor); thorium_actor_send(actor, previous, message); ++concrete_actor->spawned_senders; ++concrete_actor->spawned_senders; } else if (tag == ACTION_RING_READY && concrete_actor->step == RING_STEP_SPAWN) { concrete_actor->ready_rings++; #if 0 printf("READY: %d/%d\n", concrete_actor->ready_rings, (int)core_vector_size(&concrete_actor->spawners)); #endif if (concrete_actor->ready_rings == core_vector_size(&concrete_actor->spawners)) { thorium_actor_send_range_empty(actor, &concrete_actor->spawners, ACTION_RING_PUSH_NEXT); concrete_actor->ready_rings = 0; concrete_actor->step = RING_STEP_PUSH_NEXT; } } else if (tag == ACTION_RING_PUSH_NEXT) { previous_actor = core_vector_index_of(&concrete_actor->spawners, &name) - 1; if (previous_actor < 0) { previous_actor = core_vector_size(&concrete_actor->spawners)- 1; } printf("%d received ACTION_RING_PUSH_NEXT\n", name); thorium_message_init(message, ACTION_RING_SET_NEXT, sizeof(concrete_actor->first), &concrete_actor->first); thorium_actor_send(actor, *(int *)core_vector_at(&concrete_actor->spawners, previous_actor), message); } else if (tag == ACTION_RING_SET_NEXT) { concrete_actor->step = RING_STEP_PUSH_NEXT; thorium_message_set_action(message, ACTION_SENDER_SET_NEXT); thorium_actor_send(actor, concrete_actor->last, message); } else if (tag == ACTION_SENDER_SET_NEXT_REPLY && concrete_actor->step == RING_STEP_SPAWN) { #if 0 printf("ready senders %d/%d\n", concrete_actor->ready_senders, concrete_actor->senders); #endif if (concrete_actor->spawned_senders % 10000 == 0) { printf("spawned %d/%d\n", concrete_actor->spawned_senders, concrete_actor->senders); } if (concrete_actor->spawned_senders == concrete_actor->senders) { printf("RING_STEP_SPAWN completed.\n"); thorium_actor_send_empty(actor, *(int *)core_vector_at(&concrete_actor->spawners, 0), ACTION_RING_READY); concrete_actor->ready_senders = 0; concrete_actor->last = concrete_actor->previous; } else { new_actor = thorium_actor_spawn(actor, SCRIPT_SENDER); ++concrete_actor->spawned_senders; previous = concrete_actor->previous; thorium_message_init(message, ACTION_SENDER_SET_NEXT, sizeof(new_actor), &new_actor); thorium_actor_send(actor, previous, message); concrete_actor->previous = new_actor; } } else if (tag == ACTION_SENDER_SET_NEXT_REPLY && concrete_actor->step == RING_STEP_PUSH_NEXT) { concrete_actor->ready_senders++; printf("ACTION_SENDER_SET_NEXT_REPLY %d/%d\n", concrete_actor->ready_senders, 1); if (concrete_actor->ready_senders == 1) { thorium_actor_send_empty(actor, *(int *)core_vector_at(&concrete_actor->spawners, 0), ACTION_RING_READY); printf("RING_STEP_PUSH_NEXT completed.\n"); concrete_actor->ready_senders = 0; } } else if (tag == ACTION_RING_READY && concrete_actor->step == RING_STEP_PUSH_NEXT) { concrete_actor->ready_rings++; if (concrete_actor->ready_rings == core_vector_size(&concrete_actor->spawners)) { printf("system is ready...\n"); messages = 2000007; thorium_message_init(message, ACTION_SENDER_HELLO, sizeof(messages), &messages); thorium_actor_send(actor, concrete_actor->first, message); concrete_actor->ready_rings = 0; } } else if (tag == ACTION_SENDER_HELLO_REPLY) { thorium_actor_send_range_empty(actor, &concrete_actor->spawners, ACTION_RING_KILL); thorium_actor_send_empty(actor, concrete_actor->first, ACTION_SENDER_KILL); } else if (tag == ACTION_RING_KILL) { thorium_actor_send_to_self_empty(actor, ACTION_STOP); } }