Exemplo n.º 1
0
Arquivo: frame.c Projeto: huyba/biosal
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);
    }
}
Exemplo n.º 2
0
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;
    }
}
Exemplo n.º 3
0
Arquivo: ring.c Projeto: huyba/biosal
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);
    }
}