int thorium_transport_receive(struct thorium_transport *self, struct thorium_message *message) { int value; if (self->transport_interface == NULL) { return 0; } value = self->transport_interface->receive(self, message); if (value) { #ifdef THORIUM_TRANSPORT_DEBUG printf("TRANSPORT RECEIVE Source %d Destination %d Tag %d Count %d\n", thorium_message_source_node(message), thorium_message_destination_node(message), thorium_message_action(message), thorium_message_count(message)); #endif if (core_bitmap_get_bit_uint32_t(&self->flags, FLAG_PRINT_TRANSPORT_EVENTS)) { thorium_transport_print_event(self, EVENT_TYPE_RECEIVE, message); } } return value; }
int thorium_transport_send(struct thorium_transport *self, struct thorium_message *message) { int value; if (self->transport_interface == NULL) { return 0; } /* * Send the message through the mock transport which is * a transport profiler. */ if (core_bitmap_get_bit_uint32_t(&self->flags, FLAG_PROFILE)) { thorium_transport_profiler_send_mock(&self->transport_profiler, message); } value = self->transport_interface->send(self, message); if (value) { #ifdef THORIUM_TRANSPORT_DEBUG printf("TRANSPORT SEND Source %d Destination %d Tag %d Count %d\n", thorium_message_source_node(message), thorium_message_destination_node(message), thorium_message_action(message), thorium_message_count(message)); #endif ++self->active_request_count; if (core_bitmap_get_bit_uint32_t(&self->flags, FLAG_PRINT_TRANSPORT_EVENTS)) { thorium_transport_print_event(self, EVENT_TYPE_SEND, message); } } return value; }
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); }
void thorium_transport_print_event(struct thorium_transport *self, int type, struct thorium_message *message) { char *description; int count; int source_rank; int destination_rank; uint64_t time; description = EVENT_STRING_SEND; if (type == EVENT_TYPE_RECEIVE) description = EVENT_STRING_RECEIVE; count = thorium_message_count(message); source_rank = thorium_message_source_node(message); destination_rank = thorium_message_destination_node(message); time = core_timer_get_nanoseconds(&self->timer); time -= self->start_time; printf("thorium_transport print_event time_nanoseconds= %" PRIu64 " type= %s source= %d destination= %d count= %d\n", time, description, source_rank, destination_rank, count); }
/* * 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; }