コード例 #1
0
ファイル: worker.c プロジェクト: huyba/biosal
/*
 *This is called from within the actor running inside this worker.
 */
void thorium_worker_free_message(struct thorium_worker *worker, struct thorium_message *message)
{
    int source_worker;
    void *buffer;

    buffer = thorium_message_buffer(message);
    source_worker = thorium_message_worker(message);

    if (source_worker == worker->name) {

        /* This is from the current worker
         */
        core_memory_pool_free(&worker->outbound_message_memory_pool, buffer);
#ifdef THORIUM_WORKER_DEBUG_INJECTION
        ++worker->counter_freed_outbound_buffers_from_self;
#endif

    } else {

        /* This is from another fellow local worker
         * or from another BIOSAL node altogether.
         */

        CORE_DEBUGGER_ASSERT(thorium_message_buffer(message) != NULL);
        thorium_worker_enqueue_message_for_triage(worker, message);
    }
}
コード例 #2
0
ファイル: spate.c プロジェクト: levinas/biosal
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);
}
コード例 #3
0
void thorium_message_get_all(struct thorium_message *message, int *tag, int *count, void **buffer, int *source)
{
    *tag = thorium_message_action(message);
    *count = thorium_message_count(message);
    *buffer = thorium_message_buffer(message);
    *source = thorium_message_source(message);
}
コード例 #4
0
ファイル: systolic.c プロジェクト: bioparr/biosal
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);
    }
}
コード例 #5
0
ファイル: process.c プロジェクト: huyba/biosal
void process_ping(struct thorium_actor *self, struct thorium_message *message)
{
    int count;
    char *buffer;
    int buffer_size;
    uint64_t *bucket;
    uint64_t expected_checksum;
    uint64_t actual_checksum;
    struct process *concrete_self;

    concrete_self = (struct process *)thorium_actor_concrete_actor(self);
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);
    buffer_size = count - sizeof(expected_checksum);
    bucket = (uint64_t *)(buffer + buffer_size);
    expected_checksum = *bucket;
    actual_checksum = core_hash_data_uint64_t(buffer, buffer_size, SEED);

    if (expected_checksum != actual_checksum) {
        printf("TRANSPORT FAILED source: %d (%d) destination: %d (%d) tag: ACTION_PING count: %d"
                        " expected_checksum: %" PRIu64 " actual_checksum: %" PRIu64 "\n",
                        thorium_message_source(message),
                        thorium_message_source_node(message),
                        thorium_message_destination(message),
                        thorium_message_destination_node(message),
                        count,
                        expected_checksum, actual_checksum);

        ++concrete_self->failed;
    } else {
        ++concrete_self->passed;
    }

    thorium_actor_send_reply_empty(self, ACTION_PING_REPLY);
}
コード例 #6
0
ファイル: worker.c プロジェクト: huyba/biosal
int thorium_worker_enqueue_message_for_triage(struct thorium_worker *worker, struct thorium_message *message)
{
#ifdef THORIUM_WORKER_DEBUG_INJECTION
    int worker_name;
#endif

    CORE_DEBUGGER_ASSERT(thorium_message_buffer(message) != NULL);

    if (!core_fast_ring_push_from_producer(&worker->clean_message_ring_for_triage, message)) {

#ifdef SHOW_FULL_RING_WARNINGS
        printf("thorium_worker: Warning: ring is full, clean_message_ring_for_triage action= %x\n",
                        thorium_message_action(message));
#endif

        core_fast_queue_enqueue(&worker->clean_message_queue_for_triage, message);

#ifdef THORIUM_WORKER_DEBUG_INJECTION
    } else {
        /*
         * Update software counters.
         */
        worker_name = thorium_message_worker(message);

        if (worker_name >= 0) {
            ++worker->counter_injected_outbound_buffers_other_local_workers;
        } else {
            ++worker->counter_injected_inbound_buffers_from_thorium_core;
        }
#endif
    }

    return 1;
}
コード例 #7
0
ファイル: proxy_message.c プロジェクト: levinas/biosal
void thorium_actor_pack_proxy_message(struct thorium_actor *self, struct thorium_message *message,
                int real_source)
{
    int real_tag;
    int count;
    int new_count;
    void *buffer;
    void *new_buffer;
    int offset;
    struct core_memory_pool *ephemeral_memory;

    /*
     * pack data in this order:
     *
     * - data (count bytes)
     * - real_source
     * - real_tag
     */
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    real_tag = thorium_message_action(message);
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);

#ifdef DEBUG_BINOMIAL_TREE
    printf("DEBUG_BINOMIAL_TREE pack_proxy_message count %d source %d action %x\n", count,
                    thorium_actor_name(self),
                    real_tag);
    thorium_message_print(message);

#endif

    new_count = count + sizeof(real_source) + sizeof(real_tag);

    /* use slab allocator */
    new_buffer = core_memory_pool_allocate(ephemeral_memory, new_count);

#ifdef THORIUM_ACTOR_DEBUG
    printf("DEBUG12 core_memory_pool_allocate %p (pack proxy message)\n",
                    new_buffer);
#endif

    if (count > 0)
        core_memory_copy(new_buffer, buffer, count);

    offset = count;
    core_memory_copy((char *)new_buffer + offset, &real_source, sizeof(real_source));
    offset += sizeof(real_source);
    core_memory_copy((char *)new_buffer + offset, &real_tag, sizeof(real_tag));
    offset += sizeof(real_tag);

    thorium_message_init(message, ACTION_PROXY_MESSAGE, new_count, new_buffer);
    thorium_message_set_source(message, real_source);

#if 0
    /* free the old buffer
     */
    core_memory_free(buffer);
    buffer = NULL;
#endif
}
コード例 #8
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);
    }
}
コード例 #9
0
ファイル: message.c プロジェクト: gkthiruvathukal/biosal
void thorium_message_init_copy(struct thorium_message *self, struct thorium_message *old_message)
{
    thorium_message_init(self,
                    thorium_message_action(old_message),
                    thorium_message_count(old_message),
                    thorium_message_buffer(old_message));

    thorium_message_set_source(self,
                    thorium_message_source(old_message));
    thorium_message_set_destination(self,
                    thorium_message_destination(old_message));
}
コード例 #10
0
ファイル: worker.c プロジェクト: huyba/biosal
int thorium_worker_dequeue_message_for_triage(struct thorium_worker *worker, struct thorium_message *message)
{
    int value;

    value = core_fast_ring_pop_from_consumer(&worker->clean_message_ring_for_triage, message);

#ifdef CORE_DEBUGGER_ENABLE_ASSERT
    if (value) {
        CORE_DEBUGGER_ASSERT(thorium_message_buffer(message) != NULL);
    }
#endif

    return value;
}
コード例 #11
0
ファイル: process.c プロジェクト: huyba/biosal
void process_start(struct thorium_actor *self, struct thorium_message *message)
{
    void *buffer;
    struct process *concrete_self;

    concrete_self = (struct process *)thorium_actor_concrete_actor(self);
    buffer = thorium_message_buffer(message);

    core_vector_unpack(&concrete_self->actors, buffer);

    concrete_self->ready = 0;

    while (concrete_self->active_messages < concrete_self->concurrent_event_count) {
        process_send_ping(self);
    }
}
コード例 #12
0
ファイル: proxy_message.c プロジェクト: levinas/biosal
void thorium_actor_unpack_proxy_message(struct thorium_actor *self,
                struct thorium_message *message)
{
    int new_count;
    int tag;
    int source;
    void *buffer;
    int offset;

    buffer = thorium_message_buffer(message);
    new_count = thorium_message_count(message);
    new_count -= sizeof(source);
    new_count -= sizeof(tag);

    offset = new_count;

    source = *(int *)((char *)buffer + offset);
    offset += sizeof(source);
    tag = *(int *)((char *)buffer + offset);

#ifdef DEBUG_BINOMIAL_TREE
    printf("DEBUG_BINOMIAL_TREE unpack_proxy_message real_count %d real_source %d real_action %x\n",
                    new_count, source, tag);
#endif

    /*
     * The action can not be ACTION_INVALID because it is invalid
     * by convention.
     */
    CORE_DEBUGGER_ASSERT(tag != ACTION_INVALID);

    offset += sizeof(tag);

    /*thorium_message_init(message, tag, new_count, buffer);*/

    /*
     * Change the tag, source, and count.
     */
    thorium_message_set_source(message, source);
    thorium_message_set_action(message, tag);
    thorium_message_set_count(message, new_count);

#if 0
    printf("DEBUG unpack_proxy_message... source %d tag %d count %d\n",
                    source, tag, new_count);
#endif
}
コード例 #13
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_set_vertex_flag(struct thorium_actor *self,
                struct thorium_message *message)
{
    char *buffer;
    int count;
    int flag;
    struct biosal_dna_kmer transport_kmer;
    struct biosal_assembly_vertex *vertex;
    struct biosal_assembly_graph_store *concrete_self;
    struct core_memory_pool *ephemeral_memory;
    int position;

    concrete_self = thorium_actor_concrete_actor(self);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    biosal_dna_kmer_init_empty(&transport_kmer);
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);

    position = 0;
    position += biosal_dna_kmer_unpack(&transport_kmer, buffer, concrete_self->kmer_length,
                    ephemeral_memory, &concrete_self->transport_codec);
    core_memory_copy(&flag, buffer + position, sizeof(flag));
    position += sizeof(flag);
    CORE_DEBUGGER_ASSERT_IS_EQUAL_INT(position, count);

    CORE_DEBUGGER_ASSERT(flag >= BIOSAL_VERTEX_FLAG_START_VALUE);
    CORE_DEBUGGER_ASSERT(flag <= BIOSAL_VERTEX_FLAG_END_VALUE);

    if (flag == BIOSAL_VERTEX_FLAG_UNITIG) {
        ++concrete_self->unitig_vertex_count;
    }

#if 0
    printf("DEBUG ACTION_SET_VERTEX_FLAG %d\n", flag);
#endif
    vertex = biosal_assembly_graph_store_find_vertex(self, &transport_kmer);

    CORE_DEBUGGER_ASSERT_NOT_NULL(vertex);

    biosal_dna_kmer_destroy(&transport_kmer, ephemeral_memory);

    biosal_assembly_vertex_set_flag(vertex, flag);

    thorium_actor_send_reply_empty(self, ACTION_SET_VERTEX_FLAG_REPLY);
}
コード例 #14
0
ファイル: hello.c プロジェクト: bioparr/biosal
/* hello-hello_receive */
void hello_receive(struct thorium_actor *self, struct thorium_message *message)
{
    int tag;
    int name;
    void *buffer;
    struct hello *concrete_self;
    struct core_vector data_vector;
    int i;
    int action = thorium_message_action(message);

    concrete_self = thorium_actor_concrete_actor(self);
    name = thorium_actor_name(self);
    buffer = thorium_message_buffer(message);

    thorium_actor_log(self, "received action %d\n",
                    action);

    if (action == ACTION_START) {
        
        thorium_message_print(message);
        printf("\n");

        /*
         * Send a ping message to self.
         */
        thorium_actor_send_reply_empty(self, ACTION_MY_PING);

    }

    if (action == ACTION_MY_PING) {
        thorium_actor_send_reply_empty(self, ACTION_MY_PONG);

    }
    
    if (action == ACTION_MY_PONG) {

        thorium_actor_send_reply_empty(self, ACTION_ASK_TO_STOP);
    }

    if (action == ACTION_ASK_TO_STOP) {

        thorium_actor_send_reply_empty(self, ACTION_STOP);
    }
}
コード例 #15
0
ファイル: mpi1_pt2pt_transport.c プロジェクト: huyba/biosal
/* \see http://www.mpich.org/static/docs/v3.1/www3/MPI_Isend.html */
int thorium_mpi1_pt2pt_transport_send(struct thorium_transport *self, struct thorium_message *message)
{
    struct thorium_mpi1_pt2pt_transport *concrete_self;
    char *buffer;
    int count;
    int destination;
    int tag;
    MPI_Request *request;
    struct thorium_mpi1_pt2pt_active_request active_request;
    int worker;
    int result;

    concrete_self = thorium_transport_get_concrete_transport(self);

    worker = thorium_message_worker(message);
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);
    destination = thorium_message_destination_node(message);
    tag = DUMMY_TAG;

    thorium_mpi1_pt2pt_active_request_init(&active_request, buffer, worker);
    request = thorium_mpi1_pt2pt_active_request_request(&active_request);

    CORE_DEBUGGER_ASSERT(buffer == NULL || count > 0);

    /* get return value */
    result = MPI_Isend(buffer, count, concrete_self->datatype, destination, tag,
                    concrete_self->comm, request);

    if (result != MPI_SUCCESS) {
        return 0;
    }

    /* store the MPI_Request to test it later to know when
     * the buffer can be reused
     */
    /* \see http://blogs.cisco.com/performance/mpi_request_free-is-evil/
     */
    /*MPI_Request_free(&request);*/

    core_fast_queue_enqueue(&concrete_self->active_requests, &active_request);

    return 1;
}
コード例 #16
0
ファイル: input_controller.c プロジェクト: huyba/biosal
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);
}
コード例 #17
0
int thorium_message_unpack_double(struct thorium_message *message, int offset, double *value)
{
    int bytes;
    void *buffer;
    double *pointer;

    if (offset >= thorium_message_count(message)) {
        return -1;
    }

    bytes = sizeof(double);
    buffer = thorium_message_buffer(message);

    pointer = (double *)((char *)buffer + offset);

    *value = *pointer;

    return bytes;
}
コード例 #18
0
int thorium_message_unpack_int64_t(struct thorium_message *message, int offset, int64_t *value)
{
    int bytes;
    void *buffer;
    int64_t *pointer;

    if (offset >= thorium_message_count(message)) {
        return -1;
    }

    bytes = sizeof(int64_t);
    buffer = thorium_message_buffer(message);

    pointer = (int64_t *)((char *)buffer + offset);

    *value = *pointer;

    return bytes;
}
コード例 #19
0
ファイル: input_stream.c プロジェクト: huyba/biosal
void biosal_input_stream_count_reply_mock(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_input_stream *concrete_self;
    void *buffer;
    int count;
    struct core_vector mega_blocks;
    char *file;
    struct core_memory_pool *ephemeral_memory;
    uint64_t result;
    struct biosal_mega_block *block;

    concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(self);
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);

    core_vector_init(&mega_blocks, 0);
    core_vector_set_memory_pool(&mega_blocks, ephemeral_memory);
    core_vector_unpack(&mega_blocks, buffer);

    block = core_vector_at_last(&mega_blocks);

    result = biosal_mega_block_get_entries(block);

#if 0
    file = core_string_get(&concrete_self->file_for_parallel_counting);
#endif

    file = concrete_self->file_name;

    printf("%s/%d COUNT_IN_PARALLEL result for %s is %" PRIu64 "\n",
                    thorium_actor_script_name(self),
                    thorium_actor_name(self),
                    file,
                    result);

    core_vector_destroy(&mega_blocks);

    thorium_actor_send_buffer(self, concrete_self->controller,
                    ACTION_INPUT_COUNT_IN_PARALLEL_REPLY, count, buffer);
}
コード例 #20
0
ファイル: input_stream.c プロジェクト: huyba/biosal
void biosal_input_stream_count_in_parallel_mock(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_input_stream *concrete_self;
    void *buffer;
    int count;
    char *file;

    concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(self);

    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);

    file = concrete_self->file_name;

    printf("%s/%d receives ACTION_INPUT_COUNT_IN_PARALLEL file %s\n",
                    thorium_actor_script_name(self),
                    thorium_actor_name(self),
                    file);

    thorium_actor_send_to_self_buffer(self, ACTION_INPUT_COUNT, count, buffer);
}
コード例 #21
0
ファイル: framr.c プロジェクト: levinas/biosal
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); */
}
コード例 #22
0
ファイル: spate.c プロジェクト: levinas/biosal
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);
}
コード例 #23
0
ファイル: spate.c プロジェクト: levinas/biosal
void spate_start(struct thorium_actor *self, struct thorium_message *message)
{
    void *buffer;
    int name;
    struct spate *concrete_self;
    int spawner;
    char *directory_name;
    int already_created;
    int argc;
    char **argv;

#ifdef SPATE_VERBOSE
    thorium_actor_send_to_self_int(self, ACTION_ENABLE_LOG_LEVEL,
                    LOG_LEVEL_DEFAULT);
#endif

    concrete_self = (struct spate *)thorium_actor_concrete_actor(self);
    buffer = thorium_message_buffer(message);
    name = thorium_actor_name(self);

    /*
     * The buffer contains initial actors spawned by Thorium
     */
    core_vector_unpack(&concrete_self->initial_actors, buffer);

    if (!spate_must_print_help(self)) {
        thorium_actor_log(self, "spate/%d starts", name);
    }

    if (core_vector_index_of(&concrete_self->initial_actors, &name) == 0) {
        concrete_self->is_leader = 1;
    }

    /*
     * Abort if the actor is not the leader of the tribe.
     */
    if (!concrete_self->is_leader) {
        return;
    }

    if (spate_must_print_help(self)) {
        spate_help(self);

        spate_stop(self);
        return;
    }

    /*
     * Otherwise, the coverage distribution will take care of creating
     * the directory.
     */

    core_timer_start(&concrete_self->timer);

    /*
     * Verify if the directory already exists. If it does, don't
     * do anything as it is not a good thing to overwrite previous science
     * results.
     */
    argc = thorium_actor_argc(self);
    argv = thorium_actor_argv(self);
    directory_name = biosal_command_get_output_directory(argc, argv);
    already_created = core_directory_verify_existence(directory_name);

    if (already_created) {
        thorium_actor_log(self, "%s/%d Error: output directory \"%s\" already exists, please delete it or use a different output directory",
                        thorium_actor_script_name(self),
                        thorium_actor_name(self),
                        directory_name);
        spate_stop(self);
        return;
    }


    spawner = thorium_actor_get_spawner(self, &concrete_self->initial_actors);

    thorium_actor_send_int(self, spawner, ACTION_SPAWN, SCRIPT_INPUT_CONTROLLER);
}
コード例 #24
0
ファイル: table.c プロジェクト: bioparr/biosal
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);
        }
    }
}
コード例 #25
0
ファイル: input_controller.c プロジェクト: huyba/biosal
void biosal_input_controller_receive_command(struct thorium_actor *actor, struct thorium_message *message)
{
    struct biosal_partition_command command;
    void *buffer;
    int stream_index;
    int store_index;
    int store_name;
    uint64_t store_first;
    uint64_t store_last;
    int command_name;
    int stream_name;
    int *bucket_for_command_name;
    int bytes;
    struct biosal_input_command input_command;
    void *new_buffer;
    struct thorium_message new_message;
    struct biosal_input_controller *concrete_actor;
    int *bucket;
    int *bucket_for_consumer;
    int consumer_index;

    concrete_actor = (struct biosal_input_controller *)thorium_actor_concrete_actor(actor);
    buffer = thorium_message_buffer(message);
    biosal_partition_command_unpack(&command, buffer);
    stream_index = biosal_partition_command_stream_index(&command);

#ifdef BIOSAL_INPUT_CONTROLLER_DEBUG_COMMANDS
    printf("DEBUG biosal_input_controller_receive_command controller receives command for stream %d\n", stream_index);
    biosal_partition_command_print(&command);
#endif

    store_index = biosal_partition_command_store_index(&command);
    bucket_for_command_name = (int *)core_vector_at(&concrete_actor->partition_commands,
                    stream_index);
    bucket_for_consumer = (int *)core_vector_at(&concrete_actor->stream_consumers,
                    stream_index);

    stream_name = core_vector_at_as_int(&concrete_actor->reading_streams,
                    stream_index);

#ifdef BIOSAL_INPUT_CONTROLLER_DEBUG_COMMANDS
    printf("DEBUG stream_index %d stream_name %d\n", stream_index, stream_name);
#endif

    store_name = *(int *)core_vector_at(&concrete_actor->consumers, store_index);
    store_first = biosal_partition_command_store_first(&command);
    store_last = biosal_partition_command_store_last(&command);

    biosal_input_command_init(&input_command, store_name, store_first, store_last);

    bytes = biosal_input_command_pack_size(&input_command,
                    &concrete_actor->codec);

#ifdef BIOSAL_INPUT_CONTROLLER_DEBUG_COMMANDS
    printf("DEBUG input command\n");
    biosal_input_command_print(&input_command);

    printf("DEBUG biosal_input_controller_receive_command bytes %d\n",
                    bytes);
#endif

    new_buffer = thorium_actor_allocate(actor, bytes);
    biosal_input_command_pack(&input_command, new_buffer,
                    &concrete_actor->codec);

    thorium_message_init(&new_message, ACTION_INPUT_PUSH_SEQUENCES, bytes,
                    new_buffer);

#ifdef BIOSAL_INPUT_CONTROLLER_DEBUG_COMMANDS
    printf("DEBUG biosal_input_controller_receive_command sending ACTION_INPUT_PUSH_SEQUENCES to %d (index %d)\n",
                    stream_name, stream_index);
    biosal_input_command_print(&input_command);

    printf("SENDING COMMAND TO stream/%d\n", stream_name);
#endif

    thorium_actor_send(actor, stream_name, &new_message);

    command_name = biosal_partition_command_name(&command);

#ifdef BIOSAL_INPUT_CONTROLLER_DEBUG_COMMANDS
    printf("controller/%d processed input command %d %p\n", thorium_actor_name(actor), command_name,
                    (void *)bucket_for_command_name);
#endif

    *bucket_for_command_name = command_name;

    consumer_index = store_index;
    *bucket_for_consumer = consumer_index;

    bucket = (int *)core_vector_at(&concrete_actor->consumer_active_requests, consumer_index);

    (*bucket)++;

#ifdef BIOSAL_INPUT_CONTROLLER_DEBUG_CONSUMERS
    printf("DEBUG consumer # %d has %d active requests\n",
                        consumer_index, *bucket);
#endif
}
コード例 #26
0
ファイル: reader.c プロジェクト: bioparr/biosal
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;
    }
}
コード例 #27
0
ファイル: frame.c プロジェクト: 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);
    }
}
コード例 #28
0
void biosal_assembly_arc_classifier_push_arc_block(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_assembly_arc_classifier *concrete_self;
    int source;
    struct biosal_assembly_arc_block input_block;
    struct biosal_assembly_arc_block *output_block;
    struct core_vector output_blocks;
    struct core_memory_pool *ephemeral_memory;
    int consumer_count;
    struct core_vector *input_arcs;
    struct core_vector *output_arcs;
    int size;
    int i;
    struct biosal_assembly_arc *arc;
    void *buffer;
    int count;
    struct biosal_dna_kmer *kmer;
    int consumer_index;
    int arc_count;
    int consumer;
    struct thorium_message new_message;
    int new_count;
    void *new_buffer;
    int *bucket;
    int maximum_pending_requests;
    int maximum_buffer_length;
    int reservation;

    count = thorium_message_count(message);
    buffer = thorium_message_buffer(message);

    if (count == 0) {
        printf("Error, count is 0 (classifier_push_arc_block)\n");
        return;
    }

    concrete_self = (struct biosal_assembly_arc_classifier *)thorium_actor_concrete_actor(self);
    source = thorium_message_source(message);
    consumer_count = core_vector_size(&concrete_self->consumers);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);

    CORE_DEBUGGER_LEAK_DETECTION_BEGIN(ephemeral_memory, classify_arcs);

    core_vector_init(&output_blocks, sizeof(struct biosal_assembly_arc_block));
    core_vector_set_memory_pool(&output_blocks, ephemeral_memory);

    biosal_assembly_arc_block_init(&input_block, ephemeral_memory, concrete_self->kmer_length,
                    &concrete_self->codec);

#ifdef BIOSAL_ASSEMBLY_ARC_CLASSIFIER_DEBUG
    printf("UNPACKING\n");
#endif

    biosal_assembly_arc_block_unpack(&input_block, buffer, concrete_self->kmer_length,
                    &concrete_self->codec, ephemeral_memory);

#ifdef BIOSAL_ASSEMBLY_ARC_CLASSIFIER_DEBUG
    printf("OK\n");
#endif

    input_arcs = biosal_assembly_arc_block_get_arcs(&input_block);

    /*
     * Configure the ephemeral memory reservation.
     */
    arc_count = core_vector_size(input_arcs);
    reservation = (arc_count / consumer_count) * 2;

    core_vector_resize(&output_blocks, consumer_count);

    CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

    /*
     * Initialize output blocks.
     * There is one for each destination.
     */
    for (i = 0; i < consumer_count; i++) {

        output_block = core_vector_at(&output_blocks, i);

        biosal_assembly_arc_block_init(output_block, ephemeral_memory, concrete_self->kmer_length,
                        &concrete_self->codec);

        biosal_assembly_arc_block_reserve(output_block, reservation);
    }

    size = core_vector_size(input_arcs);

    /*
     * Classify every arc in the input block
     * and put them in output blocks.
     */

#ifdef BIOSAL_ASSEMBLY_ARC_CLASSIFIER_DEBUG
    printf("ClassifyArcs arc_count= %d\n", size);

#endif

    CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

    for (i = 0; i < size; i++) {

        arc = core_vector_at(input_arcs, i);

        kmer = biosal_assembly_arc_source(arc);

        consumer_index = biosal_dna_kmer_store_index(kmer, consumer_count,
                        concrete_self->kmer_length, &concrete_self->codec,
                        ephemeral_memory);

        output_block = core_vector_at(&output_blocks, consumer_index);

        /*
         * Make a copy of the arc and copy it.
         * It will be freed
         */

        biosal_assembly_arc_block_add_arc_copy(output_block, arc,
                        concrete_self->kmer_length, &concrete_self->codec,
                        ephemeral_memory);
    }

    /*
     * Input arcs are not needed anymore.
     */
    biosal_assembly_arc_block_destroy(&input_block, ephemeral_memory);

    CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

    /*
     * Finally, send these output blocks to consumers.
     */

    maximum_pending_requests = 0;
    maximum_buffer_length = 0;

    /*
     * Figure out the maximum buffer length tor
     * messages.
     */
    for (i = 0; i < consumer_count; i++) {

        output_block = core_vector_at(&output_blocks, i);
        new_count = biosal_assembly_arc_block_pack_size(output_block, concrete_self->kmer_length,
                    &concrete_self->codec);

        if (new_count > maximum_buffer_length) {
            maximum_buffer_length = new_count;
        }
    }

#if 0
    printf("POOL_BALANCE %d\n",
                    core_memory_pool_profile_balance_count(ephemeral_memory));
#endif

    for (i = 0; i < consumer_count; i++) {

        output_block = core_vector_at(&output_blocks, i);
        output_arcs = biosal_assembly_arc_block_get_arcs(output_block);
        arc_count = core_vector_size(output_arcs);

        /*
         * Don't send an empty message.
         */
        if (arc_count > 0) {

            /*
             * Allocation is not required because new_count <= maximum_buffer_length
             */
            new_count = biosal_assembly_arc_block_pack_size(output_block, concrete_self->kmer_length,
                    &concrete_self->codec);

            new_buffer = thorium_actor_allocate(self, maximum_buffer_length);

            CORE_DEBUGGER_ASSERT(new_count <= maximum_buffer_length);

            biosal_assembly_arc_block_pack(output_block, new_buffer, concrete_self->kmer_length,
                    &concrete_self->codec);

            thorium_message_init(&new_message, ACTION_ASSEMBLY_PUSH_ARC_BLOCK,
                    new_count, new_buffer);

            consumer = core_vector_at_as_int(&concrete_self->consumers, i);

            /*
             * Send the message.
             */
            thorium_actor_send(self, consumer, &new_message);
            thorium_message_destroy(&new_message);

            /* update event counters for control.
             */
            bucket = core_vector_at(&concrete_self->pending_requests, i);
            ++(*bucket);
            ++concrete_self->active_requests;

            if (*bucket > maximum_pending_requests) {
                maximum_pending_requests = *bucket;
            }

            if (*bucket > concrete_self->maximum_pending_request_count) {
                ++concrete_self->consumer_count_above_threshold;
            }
        }

        CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

#if 0
        printf("i = %d\n", i);
#endif

        /*
         * Destroy output block.
         */
        biosal_assembly_arc_block_destroy(output_block,
                    ephemeral_memory);

        CORE_DEBUGGER_LEAK_CHECK_DOUBLE_FREE(ephemeral_memory);
        CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));
    }

    core_vector_destroy(&output_blocks);

    CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

    CORE_DEBUGGER_LEAK_CHECK_DOUBLE_FREE(ephemeral_memory);

    /*
     * Check if a response must be sent now.
     */

    ++concrete_self->received_blocks;
    concrete_self->source = source;

    /*
     * Only send a direct reply if there is enough memory.
     *
     * As long as maximum_pending_requests is lower than maximum_pending_request_count,
     * there is still space for at least one additional request.
     */
    if (maximum_pending_requests < concrete_self->maximum_pending_request_count
            && core_memory_has_enough_bytes()) {

        thorium_actor_send_empty(self, concrete_self->source,
                    ACTION_ASSEMBLY_PUSH_ARC_BLOCK_REPLY);
    } else {

        concrete_self->producer_is_waiting = 1;
    }

    CORE_DEBUGGER_LEAK_DETECTION_END(ephemeral_memory, classify_arcs);
}
コード例 #29
0
ファイル: input_stream.c プロジェクト: huyba/biosal
void biosal_input_stream_count_in_parallel(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_input_stream *concrete_self;
    char *file;
    uint64_t file_size;
    uint64_t start_offset;
    uint64_t end_offset;
    void *buffer;
    int spawner;
    int i;
    int size;
    uint64_t parallel_block_size;

    /*
     * The block size for deciding when to spawn new actors for
     * I/O.
     */
    parallel_block_size = 536870912;

    /*
    parallel_block_size = 0;
    --parallel_block_size;
     */

    /*
     * Approach:
     *
     * 1. Check number of bytes.
     * 2. Determine the number of streams.
     * 3. Spawn streams using a manager.
     * 4. Set the offsets for each stream
     * 5. Set ask them to count
     */
    concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(self);
    buffer = thorium_message_buffer(message);

    core_vector_unpack(&concrete_self->spawners, buffer);

    file = concrete_self->file_name;

    file_size = core_file_get_size(file);

    printf("COUNT_IN_PARALLEL %s %" PRIu64 "\n",
                    file, file_size);

    start_offset = 0;

    i = 0;
    while (start_offset < file_size) {

        end_offset = start_offset + parallel_block_size - 1;

        if (end_offset > file_size - 1 || end_offset < start_offset) {
            end_offset = file_size - 1;
        }


        core_vector_push_back_uint64_t(&concrete_self->start_offsets, start_offset);
        core_vector_push_back_uint64_t(&concrete_self->end_offsets, end_offset);

        printf("DEBUG PARALLEL BLOCK %s %i %" PRIu64 " %" PRIu64 "\n",
                        file,
                        i,
                        start_offset,
                        end_offset);

        start_offset = end_offset + 1;
        ++i;
    }

    size = core_vector_size(&concrete_self->start_offsets);

    thorium_actor_add_action(self, ACTION_SPAWN_REPLY, biosal_input_stream_spawn_reply);

    printf("DEBUG stream/%d spawns %d streams for counting\n",
                    thorium_actor_name(self),
                    size);

    for (i = 0; i < size; i++) {

        spawner = thorium_actor_get_random_spawner(self, &concrete_self->spawners);

        thorium_actor_send_int(self, spawner, ACTION_SPAWN,
                SCRIPT_INPUT_STREAM);
    }
}
コード例 #30
0
ファイル: input_stream.c プロジェクト: huyba/biosal
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);
    }
}