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 }
void ring_receive(struct thorium_actor *actor, struct thorium_message *message) { int tag; int new_actor; int previous; int name; struct ring *concrete_actor; int messages; int previous_actor; char *buffer; int destination; concrete_actor = (struct ring *)thorium_actor_concrete_actor(actor); tag = thorium_message_action(message); buffer = thorium_message_buffer(message); name = thorium_actor_name(actor); if (tag == ACTION_START) { core_vector_init(&concrete_actor->spawners, 0); core_vector_unpack(&concrete_actor->spawners, buffer); printf("actor %d ACTION_START, %d spawners\n", name, (int)core_vector_size(&concrete_actor->spawners)); destination = *(int *)core_vector_at(&concrete_actor->spawners, 0); thorium_actor_send_empty(actor, destination, ACTION_RING_READY); } else if (tag == ACTION_RING_READY && concrete_actor->step == RING_STEP_RECEIVE_SPAWNERS) { concrete_actor->ready_rings++; if (concrete_actor->ready_rings == (int)core_vector_size(&concrete_actor->spawners)) { thorium_actor_send_range_empty(actor, &concrete_actor->spawners, ACTION_RING_SPAWN); concrete_actor->step = RING_STEP_SPAWN; concrete_actor->ready_rings = 0; } } else if (tag == ACTION_RING_SPAWN) { printf("actor/%d is spawning %d senders\n", thorium_actor_name(actor), concrete_actor->senders); concrete_actor->step = RING_STEP_SPAWN; new_actor = thorium_actor_spawn(actor, SCRIPT_SENDER); concrete_actor->first = new_actor; previous = new_actor; new_actor = thorium_actor_spawn(actor, SCRIPT_SENDER); concrete_actor->previous = new_actor; thorium_message_init(message, ACTION_SENDER_SET_NEXT, sizeof(new_actor), &new_actor); thorium_actor_send(actor, previous, message); ++concrete_actor->spawned_senders; ++concrete_actor->spawned_senders; } else if (tag == ACTION_RING_READY && concrete_actor->step == RING_STEP_SPAWN) { concrete_actor->ready_rings++; #if 0 printf("READY: %d/%d\n", concrete_actor->ready_rings, (int)core_vector_size(&concrete_actor->spawners)); #endif if (concrete_actor->ready_rings == core_vector_size(&concrete_actor->spawners)) { thorium_actor_send_range_empty(actor, &concrete_actor->spawners, ACTION_RING_PUSH_NEXT); concrete_actor->ready_rings = 0; concrete_actor->step = RING_STEP_PUSH_NEXT; } } else if (tag == ACTION_RING_PUSH_NEXT) { previous_actor = core_vector_index_of(&concrete_actor->spawners, &name) - 1; if (previous_actor < 0) { previous_actor = core_vector_size(&concrete_actor->spawners)- 1; } printf("%d received ACTION_RING_PUSH_NEXT\n", name); thorium_message_init(message, ACTION_RING_SET_NEXT, sizeof(concrete_actor->first), &concrete_actor->first); thorium_actor_send(actor, *(int *)core_vector_at(&concrete_actor->spawners, previous_actor), message); } else if (tag == ACTION_RING_SET_NEXT) { concrete_actor->step = RING_STEP_PUSH_NEXT; thorium_message_set_action(message, ACTION_SENDER_SET_NEXT); thorium_actor_send(actor, concrete_actor->last, message); } else if (tag == ACTION_SENDER_SET_NEXT_REPLY && concrete_actor->step == RING_STEP_SPAWN) { #if 0 printf("ready senders %d/%d\n", concrete_actor->ready_senders, concrete_actor->senders); #endif if (concrete_actor->spawned_senders % 10000 == 0) { printf("spawned %d/%d\n", concrete_actor->spawned_senders, concrete_actor->senders); } if (concrete_actor->spawned_senders == concrete_actor->senders) { printf("RING_STEP_SPAWN completed.\n"); thorium_actor_send_empty(actor, *(int *)core_vector_at(&concrete_actor->spawners, 0), ACTION_RING_READY); concrete_actor->ready_senders = 0; concrete_actor->last = concrete_actor->previous; } else { new_actor = thorium_actor_spawn(actor, SCRIPT_SENDER); ++concrete_actor->spawned_senders; previous = concrete_actor->previous; thorium_message_init(message, ACTION_SENDER_SET_NEXT, sizeof(new_actor), &new_actor); thorium_actor_send(actor, previous, message); concrete_actor->previous = new_actor; } } else if (tag == ACTION_SENDER_SET_NEXT_REPLY && concrete_actor->step == RING_STEP_PUSH_NEXT) { concrete_actor->ready_senders++; printf("ACTION_SENDER_SET_NEXT_REPLY %d/%d\n", concrete_actor->ready_senders, 1); if (concrete_actor->ready_senders == 1) { thorium_actor_send_empty(actor, *(int *)core_vector_at(&concrete_actor->spawners, 0), ACTION_RING_READY); printf("RING_STEP_PUSH_NEXT completed.\n"); concrete_actor->ready_senders = 0; } } else if (tag == ACTION_RING_READY && concrete_actor->step == RING_STEP_PUSH_NEXT) { concrete_actor->ready_rings++; if (concrete_actor->ready_rings == core_vector_size(&concrete_actor->spawners)) { printf("system is ready...\n"); messages = 2000007; thorium_message_init(message, ACTION_SENDER_HELLO, sizeof(messages), &messages); thorium_actor_send(actor, concrete_actor->first, message); concrete_actor->ready_rings = 0; } } else if (tag == ACTION_SENDER_HELLO_REPLY) { thorium_actor_send_range_empty(actor, &concrete_actor->spawners, ACTION_RING_KILL); thorium_actor_send_empty(actor, concrete_actor->first, ACTION_SENDER_KILL); } else if (tag == ACTION_RING_KILL) { thorium_actor_send_to_self_empty(actor, ACTION_STOP); } }