예제 #1
0
void thorium_mpi1_pt2pt_transport_destroy(struct thorium_transport *self)
{
    struct thorium_mpi1_pt2pt_transport *concrete_self;
    int result;
    struct thorium_mpi1_pt2pt_active_request active_request;

    concrete_self = thorium_transport_get_concrete_transport(self);

    while (core_queue_dequeue(&concrete_self->active_requests, &active_request)) {
        thorium_mpi1_pt2pt_active_request_destroy(&active_request);
    }

    core_queue_destroy(&concrete_self->active_requests);

    /*
     * \see http://www.mpich.org/static/docs/v3.1/www3/MPI_Comm_free.html
     */
    result = MPI_Comm_free(&concrete_self->comm);

    if (result != MPI_SUCCESS) {
        return;
    }

    result = MPI_Finalize();

    if (result != MPI_SUCCESS) {
        return;
    }
}
예제 #2
0
int thorium_mpi1_pt2pt_transport_test(struct thorium_transport *self, struct thorium_worker_buffer *worker_buffer)
{
    struct thorium_mpi1_pt2pt_active_request active_request;
    struct thorium_mpi1_pt2pt_transport *concrete_self;
    void *buffer;
    int worker;

    concrete_self = thorium_transport_get_concrete_transport(self);

    if (core_queue_dequeue(&concrete_self->active_requests, &active_request)) {

        if (thorium_mpi1_pt2pt_active_request_test(&active_request)) {

            worker = thorium_mpi1_pt2pt_active_request_worker(&active_request);
            buffer = thorium_mpi1_pt2pt_active_request_buffer(&active_request);

            thorium_worker_buffer_init(worker_buffer, worker, buffer);

            thorium_mpi1_pt2pt_active_request_destroy(&active_request);

            return 1;

        /* Just put it back in the FIFO for later */
        } else {
            core_queue_enqueue(&concrete_self->active_requests, &active_request);

            return 0;
        }
    }

    return 0;
}
예제 #3
0
void biosal_input_controller_prepare_spawners(struct thorium_actor *actor, struct thorium_message *message)
{
    int spawner;
    struct biosal_input_controller *concrete_actor;

    concrete_actor = (struct biosal_input_controller *)thorium_actor_concrete_actor(actor);

#ifdef BIOSAL_INPUT_CONTROLLER_DEBUG
    printf("DEBUG biosal_input_controller_prepare_spawners \n");
#endif

    /* spawn an actor of the same script on every spawner to load required
     * scripts on all nodes
     */
    if (core_queue_dequeue(&concrete_actor->unprepared_spawners, &spawner)) {

        thorium_actor_send_int(actor, spawner, ACTION_SPAWN, thorium_actor_script(actor));
        concrete_actor->state = BIOSAL_INPUT_CONTROLLER_STATE_PREPARE_SPAWNERS;
    }
}
예제 #4
0
파일: test_queue.c 프로젝트: bioparr/biosal
int main(int argc, char **argv)
{
    BEGIN_TESTS();

    {
        /* test when inserting more than array size */

        struct core_queue queue;
        int i;
        core_queue_init(&queue, sizeof(int));

        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        i = 16;
        while (i--) {
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &i), 1);
        }

        i = 16;
        while (i--) {
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &i), 1);
        }

        TEST_INT_EQUALS(core_queue_full(&queue), 0);

        i = 16;
        while (i--) {
            int item;
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &item), 1);
        }

        i = 16;
        while (i--) {
            int item;
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &item), 1);
        }

        core_queue_destroy(&queue);
    }

    {
        /* push 1000 elements, and verify them after */

        struct core_queue queue;
        int i;
        core_queue_init(&queue, sizeof(int));

        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        i = 1000;
        while (i--) {
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &i), 1);
        }

        TEST_INT_EQUALS(core_queue_full(&queue), 0);

        i = 1000;
        while (i--) {
            int item;
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &item), 1);
            TEST_INT_EQUALS(item, i);
            /* printf("%i %i\n", item, i); */
        }

        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        core_queue_destroy(&queue);
    }

    {
        /* use array size of 1 and 2000 elements */

        struct core_queue queue;
        int i;
        core_queue_init(&queue, sizeof(int));

        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        i = 2000;
        while (i--) {
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &i), 1);
        }

        TEST_INT_EQUALS(core_queue_full(&queue), 0);

        i = 2000;
        while (i--) {
            int item;
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &item), 1);
            TEST_INT_EQUALS(item, i);
            /* printf("%i %i\n", item, i); */
        }

        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        core_queue_destroy(&queue);
    }

    {
        /* stress test the code by inserting one element,
           and then removing. */

        struct core_queue queue;
        int i;
        int expected;
        core_queue_init(&queue, sizeof(int));

        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        i = 3000;
        while (i--) {
            expected = i;

            TEST_INT_EQUALS(core_queue_enqueue(&queue, &i), 1);
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &i), 1);

            TEST_INT_EQUALS(i, expected);

            TEST_INT_EQUALS(core_queue_empty(&queue), 1);
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &i), 1);
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &i), 1);

            TEST_INT_EQUALS(i, expected);
        }

        TEST_INT_EQUALS(core_queue_full(&queue), 0);
        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        /*
         * At any time, there is 0 or 1 elements in the queue.
         */
        /*
        core_queue_print(&queue);
        */

        TEST_INT_IS_LOWER_THAN(core_queue_capacity(&queue), 100);

        core_queue_destroy(&queue);
    }

    {
        struct core_queue queue;
        int i;
        int value;
        core_queue_init(&queue, sizeof(int));

#if 0
        printf("Test 3\n");
#endif
        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        i = 3000;
        while (i--) {
            value = i;
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &value), 1);
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &value), 1);
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &value), 1);
        }

#if 0
        printf("Test 3, size %d\n",
                        core_queue_size(&queue));
#endif

        core_queue_destroy(&queue);
    }

    {
        struct core_queue queue;
        int i;
        int value;
        core_queue_init(&queue, sizeof(int));

#if 0
        printf("Test 4\n");
#endif
        TEST_INT_EQUALS(core_queue_empty(&queue), 1);

        i = 3000000;
        while (i--) {
            value = i;
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &value), 1);
            TEST_INT_EQUALS(core_queue_enqueue(&queue, &value), 1);
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &value), 1);
            TEST_INT_EQUALS(core_queue_dequeue(&queue, &value), 1);
        }

#if 0
        printf("Test 4, size %d\n",
                        core_queue_size(&queue));
#endif

        core_queue_destroy(&queue);
    }

    END_TESTS();

    return 0;
}
예제 #5
0
/*
 * This is O(n), that is if all thorium nodes have a buffer to flush.
 */
void thorium_message_multiplexer_test(struct thorium_message_multiplexer *self)
{
    /*
     * Check if the multiplexer has waited enough.
     */

    int index;
    struct thorium_multiplexed_buffer *multiplexed_buffer;
    int buffer_is_ready;

#if defined(THORIUM_MULTIPLEXER_USE_TREE) || defined(THORIUM_MULTIPLEXER_USE_HEAP)
    uint64_t *lowest_key;
    int *index_bucket;
#endif

    if (CORE_BITMAP_GET_FLAG(self->flags, FLAG_DISABLED)) {
        return;
    }

#ifdef THORIUM_MULTIPLEXER_TRACK_BUFFERS_WITH_CONTENT
    /*
     * Nothing to do, there is nothing to flush
     * in the system.
     */
    if (core_set_empty(&self->buffers_with_content)) {
        return;
    }
#endif

#if 1
    /*
     * Don't flush anything if the outbound ring is full,
     * which means there is congestion.
     *
     * This means that the throughput is at its maximum value. In that case,
     * it is better to generate even larger messages.
     */
    if (thorium_worker_has_outbound_traffic_congestion(self->worker)) {
        return;
    }

#endif

#ifdef DEBUG_MULTIPLEXER_TEST
    if (size >= DEBUG_MINIMUM_COUNT)
        thorium_printf("DEBUG multiplexer_test buffers with content: %d\n",
                    size);
#endif

#ifdef CHECK_PREDICTED_TRAFFIC_REDUCTION
    /*
     * 0.95 corresponds to 20 actor messages in 1 network message.
     * 0.90 corresponds to 10 actor messages in 1 network message.
     */
    acceptable_traffic_reduction = 0.90;
#endif

    /*
     * Get the destination with the oldest buffer.
     * If this one has not waited enough, then any other more recent
     * buffer has not waited enough neither.
     */
    while (1) {
#ifdef THORIUM_MULTIPLEXER_USE_TREE
        lowest_key = core_red_black_tree_get_lowest_key(&self->timeline);
        /*
        * The timeline is empty.
        */
        if (lowest_key == NULL)
            return;

#elif defined(THORIUM_MULTIPLEXER_USE_HEAP)
        lowest_key = NULL;
        core_binary_heap_get_root(&self->timeline, (void **)&lowest_key,
                            (void **)&index_bucket);
        /*
        * The timeline is empty.
        */
        if (lowest_key == NULL)
            return;

#elif defined(THORIUM_MULTIPLEXER_USE_QUEUE)

        if (!core_queue_dequeue(&self->timeline, &index)) {
            return;
        }

#endif

        /*
        * Get the index.
        * The index is the destination.
        */
#ifdef THORIUM_MULTIPLEXER_USE_TREE
        index_bucket = core_red_black_tree_get(&self->timeline, lowest_key);
        index = *index_bucket;
#endif

        multiplexed_buffer = core_vector_at(&self->buffers, index);

        buffer_is_ready = thorium_message_multiplexer_buffer_is_ready(self, multiplexed_buffer);

        /*
        * The oldest item is too recent.
        * Therefore, all the others are too recent too
        * because the timeline is ordered.
        */
        if (!buffer_is_ready) {
#ifdef THORIUM_MULTIPLEXER_USE_QUEUE
            core_queue_enqueue(&self->timeline, &index);
#endif
            return;
        }

#ifdef CHECK_OUTBOUND_THROUGHPUT
        /*
        * Don't flush now since the transport layer has already reached its maximum
        * throughput.
        */
        if (thorium_worker_has_reached_maximum_outbound_throughput(self->worker)
                      && traffic_reduction < acceptable_traffic_reduction) {
#ifdef THORIUM_MULTIPLEXER_USE_QUEUE
            core_queue_enqueue(&self->timeline, &index);
#endif
            return;
        }
#endif

    /*
     * Remove the object from the timeline.
     */

#ifdef THORIUM_MULTIPLEXER_USE_TREE
        core_red_black_tree_delete(&self->timeline, lowest_key);
#elif defined(THORIUM_MULTIPLEXER_USE_HEAP)
        core_binary_heap_delete_root(&self->timeline);
#endif

#ifdef VERIFY_TARGET
        /*
        * Verify if the buffer can grow more.
        */
        if (!thorium_multiplexed_buffer_has_reached_target(multiplexed_buffer)) {
            thorium_multiplexed_buffer_set_time(multiplexed_buffer, time);

            core_red_black_tree_add_key_and_value(&self->timeline, &time, &index);

            return;
        }
#endif

        /*
        * The item won't have content in the case were _flush()
        * was called elsewhere with FORCE_YES_SIZE.
        */
#ifdef THORIUM_MULTIPLEXER_TRACK_BUFFERS_WITH_CONTENT
        if (core_set_find(&self->buffers_with_content, &index)) {
#endif
            thorium_message_multiplexer_flush(self, index, FORCE_YES_TIME);

#ifdef THORIUM_MULTIPLEXER_TRACK_BUFFERS_WITH_CONTENT
        }
#endif

        /*
         * Otherwise, keep flushing stuff.
         * This will eventually end anyway.
         */
    }
}
예제 #6
0
void biosal_sequence_partitioner_receive(struct thorium_actor *actor, struct thorium_message *message)
{
    int tag;
    int source;
    int count;
    void *buffer;
    int bytes;
    struct biosal_sequence_partitioner *concrete_actor;
    struct biosal_partition_command command;
    struct thorium_message response;
    int command_number;
    struct biosal_partition_command *active_command;
    int stream_index;
    struct biosal_partition_command *command_bucket;
    int i;

    thorium_message_get_all(message, &tag, &count, &buffer, &source);

    concrete_actor = (struct biosal_sequence_partitioner *)thorium_actor_concrete_actor(actor);

    if (tag == ACTION_SEQUENCE_PARTITIONER_SET_BLOCK_SIZE) {
        thorium_message_unpack_int(message, 0, &concrete_actor->block_size);
        thorium_actor_send_reply_empty(actor, ACTION_SEQUENCE_PARTITIONER_SET_BLOCK_SIZE_REPLY);

        biosal_sequence_partitioner_verify(actor);
/*
        printf("DEBUG biosal_sequence_partitioner_receive received block size\n");
        */
    } else if (tag == ACTION_SEQUENCE_PARTITIONER_SET_ENTRY_VECTOR) {

            /*
        printf("DEBUG biosal_sequence_partitioner_receive unpacking vector, %d bytes\n",
                        count);
                        */

        core_vector_init(&concrete_actor->stream_entries, 0);
        core_vector_unpack(&concrete_actor->stream_entries, buffer);

        /*
        printf("DEBUG after unpack\n");
        */

        thorium_actor_send_reply_empty(actor, ACTION_SEQUENCE_PARTITIONER_SET_ENTRY_VECTOR_REPLY);

        /*
        printf("DEBUG biosal_sequence_partitioner_receive received received entry vector\n");
        */
        biosal_sequence_partitioner_verify(actor);

    } else if (tag == ACTION_SEQUENCE_PARTITIONER_SET_ACTOR_COUNT) {

        thorium_message_unpack_int(message, 0, &concrete_actor->store_count);
        thorium_actor_send_reply_empty(actor, ACTION_SEQUENCE_PARTITIONER_SET_ACTOR_COUNT_REPLY);

        biosal_sequence_partitioner_verify(actor);
        /*
        printf("DEBUG biosal_sequence_partitioner_receive received received store count\n");
        */

    } else if (tag == ACTION_SEQUENCE_PARTITIONER_GET_COMMAND) {

        if (core_queue_dequeue(&concrete_actor->available_commands, &command)) {

            bytes = biosal_partition_command_pack_size(&command);

            /*
            printf("DEBUG partitioner has command, packing %d bytes!\n", bytes);
            */

            buffer = thorium_actor_allocate(actor, bytes);
            biosal_partition_command_pack(&command, buffer);

            thorium_message_init(&response, ACTION_SEQUENCE_PARTITIONER_GET_COMMAND_REPLY,
                            bytes, buffer);
            thorium_actor_send_reply(actor, &response);

            /* store the active command
             */
            command_number = biosal_partition_command_name(&command);
            command_bucket = (struct biosal_partition_command *)core_map_add(&concrete_actor->active_commands,
                            &command_number);
            *command_bucket = command;

            /* there may be other command available too !
             */
        }

    } else if (tag == ACTION_SEQUENCE_PARTITIONER_GET_COMMAND_REPLY_REPLY) {
        /*
         * take the name of the command, find it in the active
         * command, generate a new command, and send ACTION_SEQUENCE_PARTITIONER_COMMAND_IS_READY
         * as a reply
         */

        thorium_message_unpack_int(message, 0, &command_number);

        active_command = core_map_get(&concrete_actor->active_commands,
                        &command_number);

        if (active_command == NULL) {
            return;
        }

        stream_index = biosal_partition_command_stream_index(active_command);
        active_command = NULL;
        core_map_delete(&concrete_actor->active_commands,
                        &command_number);

        biosal_sequence_partitioner_generate_command(actor, stream_index);

        if (core_map_size(&concrete_actor->active_commands) == 0
                        && core_queue_size(&concrete_actor->available_commands) == 0) {

            thorium_actor_send_reply_empty(actor, ACTION_SEQUENCE_PARTITIONER_FINISHED);
        }

    } else if (tag == ACTION_ASK_TO_STOP
                    && source == thorium_actor_supervisor(actor)) {

#ifdef BIOSAL_SEQUENCE_PARTITIONER_DEBUG
        printf("DEBUG biosal_sequence_partitioner_receive ACTION_ASK_TO_STOP\n");
#endif

        thorium_actor_send_to_self_empty(actor,
                        ACTION_STOP);

    } else if (tag == ACTION_SEQUENCE_PARTITIONER_PROVIDE_STORE_ENTRY_COUNTS_REPLY) {
        /* generate commands
         */
        for (i = 0; i < core_vector_size(&concrete_actor->stream_entries); i++) {

            biosal_sequence_partitioner_generate_command(actor, i);
        }
    }
}