Beispiel #1
0
int thorium_worker_dequeue_message(struct thorium_worker *worker, struct thorium_message *message)
{
    int answer;

    answer = core_fast_ring_pop_from_consumer(&worker->outbound_message_queue, message);

    if (answer) {
        thorium_message_set_worker(message, worker->name);
    }

    return answer;
}
Beispiel #2
0
void thorium_message_multiplexer_flush(struct thorium_message_multiplexer *self, int index, int force)
{
    char *buffer;
    struct thorium_message message;
    int tag;
    int count;
    int current_size;
    int maximum_size;
    struct thorium_multiplexed_buffer *multiplexed_buffer;
    int destination_node;
    /*
    int elapsed;
    int message_count;
    */

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

#ifdef THORIUM_MULTIPLEXER_TRACK_BUFFERS_WITH_CONTENT
#ifdef CORE_DEBUGGER_ASSERT_ENABLED
    if (!(core_set_find(&self->buffers_with_content, &index))) {
        multiplexed_buffer = core_vector_at(&self->buffers, index);
        thorium_printf("index %d has no content\n", index);

        thorium_multiplexed_buffer_print(multiplexed_buffer);
    }
#endif

    CORE_DEBUGGER_ASSERT(core_set_find(&self->buffers_with_content, &index));
#endif

    multiplexed_buffer = core_vector_at(&self->buffers, index);
    current_size = thorium_multiplexed_buffer_current_size(multiplexed_buffer);
    maximum_size = thorium_multiplexed_buffer_maximum_size(multiplexed_buffer);

    /*
     * The buffer was still in the timeline, but it was flushed elsewhere.
     */
    if (current_size == 0) {
        return;

        /*
    if (force == FORCE_NO && current_size < maximum_size) {
        return;

    } else if (force == FORCE_YES_TIME) {
        elapsed = core_timer_get_nanoseconds(&self->timer) - multiplexed_buffer->timestamp_;

        if (elapsed < self->timeout_in_nanoseconds) {
            return;
        }
    } else if (force == FORCE_YES_DOA) {
        message_count = multiplexed_buffer->message_count_;

        if (message_count < self->degree_of_aggregation_limit) {
            return;
        }
        */
    }

#ifdef CORE_DEBUGGER_ASSERT_ENABLED
    if (current_size <= 0)
        thorium_printf("current_size %d maximum_size %d\n", current_size, maximum_size);
#endif

    CORE_DEBUGGER_ASSERT(current_size > 0);

    buffer = thorium_multiplexed_buffer_buffer(multiplexed_buffer);

    count = current_size + THORIUM_MESSAGE_METADATA_SIZE;

    tag = ACTION_MULTIPLEXER_MESSAGE;

    /*
     * This count does not include metadata for the final big message.
     *
     * Avoid this copy by using an array of pointers in the first place.
     */

    destination_node = index;

    thorium_message_init(&message, tag, count, buffer);
    thorium_message_set_destination(&message,
                    destination_node);
    thorium_message_set_source(&message,
            thorium_node_name(self->node));
    /*
     * Mark the message so that the buffer is eventually sent back here
     * for recycling.
     */
    thorium_message_set_worker(&message, thorium_worker_name(self->worker));

    thorium_message_write_metadata(&message);

#ifdef DEBUG_MULTIPLEXER_FLUSH
    thorium_printf("DEBUG_MULTIPLEXER thorium_message_multiplexer_flush index %d buffer %p force %d current_size %d maximum_size %d"
                    " destination_node %d\n",
                    index, buffer, force,
                    current_size, maximum_size,
                    thorium_message_destination_node(&message));

    thorium_printf("message in flush\n");
    thorium_multiplexed_buffer_print(multiplexed_buffer);
    thorium_message_print(&message);
#endif

    CORE_DEBUGGER_ASSERT_NOT_NULL(self->worker);

    /*
     * Make a copy of the buffer because the multiplexer does not have communication buffers.
     */
    thorium_worker_enqueue_outbound_message(self->worker, &message);

    /*
    thorium_printf("MULTIPLEXER FLUSH\n");
    */

    ++self->real_message_count;
    thorium_message_destroy(&message);

    thorium_multiplexed_buffer_reset(multiplexed_buffer);

#ifdef THORIUM_MULTIPLEXER_TRACK_BUFFERS_WITH_CONTENT
    core_set_delete(&self->buffers_with_content, &index);
#endif
}
Beispiel #3
0
/*
 * Returns 1 if the message was demultiplexed.
 *
 * This is O(1) in regard to the number of thorium nodes.
 */
int thorium_message_multiplexer_demultiplex(struct thorium_message_multiplexer *self,
                struct thorium_message *message)
{
    /*
     * Algorithm:
     *
     * get tag.
     * if tag is ACTION_MULTIPLEXER_MESSAGE
     *     for every enclosed message
     *         call thorium_node_prepare_received_message
     *         call thorium_node_dispatch_message()
     *     return 1
     *
     * return 0
     */

    int count;
    char *buffer;
    struct thorium_message new_message;
    int new_count;
    void *new_buffer;
    int position;
    struct core_memory_pool *pool;
    int messages;
    int tag;
    int source_node;
    int destination_node;
    int current_node;
    int routing_destination;

#ifdef DEBUG_MULTIPLEXER
    thorium_printf("demultiplex message\n");
    thorium_message_print(message);
#endif

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

    tag = thorium_message_action(message);

    if (tag != ACTION_MULTIPLEXER_MESSAGE) {
        return 0;
    }

    /*
    thorium_printf("MULTIPLEXER demultiplex\n");
    */

    messages = 0;
    tracepoint(thorium_node, demultiplex_enter, self->node->name,
                    self->node->tick, messages);

    source_node = thorium_message_source_node(message);
    destination_node = thorium_message_destination_node(message);

    /*
     * Remove the metadata from the count.
     */
    thorium_message_remove_metadata_from_count(message);

    count = thorium_message_count(message);

    buffer = thorium_message_buffer(message);

    pool = thorium_worker_get_outbound_message_memory_pool(self->worker);

    position = 0;

    /*
     * Inject a message for each enclosed message.
     */
    while (position < count) {
        core_memory_copy(&new_count, buffer + position, sizeof(new_count));
        position += sizeof(new_count);

        new_buffer = core_memory_pool_allocate(pool, new_count);
        core_memory_copy(new_buffer, buffer + position, new_count);

        thorium_message_init_with_nodes(&new_message, new_count, new_buffer,
                        source_node, destination_node);

        thorium_node_prepare_received_message(self->node, &new_message);

        /*
         * For these demultiplexed messages, there are 2 outcomes:
         *
         * 1) the message must be delivered locally;
         * 2) the message must be forward because this is a middle node in
         *    the route.
         */
        /*
        thorium_printf("demultiplex: \n");
        thorium_message_print(&new_message);
        thorium_printf("\n");
*/
        /*
         * Mark the message for recycling.
         */
        thorium_message_set_worker(&new_message, thorium_worker_name(self->worker));

#ifdef CORE_DEBUGGER_ASSERT_ENABLED
        if (thorium_message_action(&new_message) == ACTION_INVALID) {
            thorium_printf("Error invalid action DEMUL Multiplexer position %d count %d new_count %d\n",
                            position, count, new_count);
            thorium_message_print(&new_message);
        }
#endif

        CORE_DEBUGGER_ASSERT(thorium_message_action(&new_message) != ACTION_INVALID);

        /*
        thorium_printf("DEMULTIPLEX_MESSAGE\n");
        */

        /*
        thorium_printf("demultiplex, local delivery: \n");
        thorium_message_print(&new_message);
        */

        current_node = self->node->name;
        routing_destination = new_message.routing_destination;

        CORE_DEBUGGER_ASSERT(routing_destination >= 0);

        /*
         * This is a local delivery, nothing to see here.
         */
        if (routing_destination == current_node) {

            thorium_worker_send_local_delivery(self->worker, &new_message);

        /*
         * Otherwise, get the next node in the route and send the
         * payload there since we can not do anything with it here.
         */
        } else {

            /*
             * Export the message to another node.
             * To do this, use an exporter worker.
             */
            thorium_worker_send_for_multiplexer(self->worker,
                            &new_message);
        }

        /*
        thorium_message_destroy(&new_message);
        */

        position += new_count;
        ++messages;
    }

    CORE_DEBUGGER_ASSERT(messages > 0);

#ifdef DEBUG_MULTIPLEXER
    thorium_printf("thorium_message_multiplexer_demultiplex %d messages\n",
                    messages);
#endif

    tracepoint(thorium_node, demultiplex_exit, self->node->name,
                    self->node->tick, messages);

    return 1;
}