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; } }
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; }
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; } }
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; }
/* * 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. */ } }
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); } } }