// fill all data packets to sender and wait for it to complete and signal responser by calling responser_connection_closed. int send_chunk(bt_responser_t * res, int peer, int chunk_id){ printf("Sending Chunk %d to %d\n", chunk_id, peer); if(res->uploadingto[peer]){ printf("Already in progress\n"); return -1; } if(res->uploading_cnt >= config.max_conn){ printf("Too many connections\n"); return -1; } int sender_id = find_sender(); if(sender_id == -1){ printf("No sender available!\n"); return -1; } senders[sender_id].peer = peer; res->uploadingto[peer] = 1; ++ res->uploading_cnt; static char buf[BT_PACKET_DATA_SIZE]; FILE * fin = fopen(res->chunk_file, "r"); fseek(fin, chunk_id * BT_CHUNK_SIZE, SEEK_SET); int i; for(i=0; i<BT_CHUNK_SIZE; i+=BT_PACKET_DATA_SIZE){ fread(buf, BT_PACKET_DATA_SIZE, 1, fin); #ifdef JUNK // add crap data int junk_pos = 0; for(junk_pos=0; junk_pos< 20; junk_pos++) buf[100+junk_pos] = 'a' + junk_pos; #endif data_packet_t * packet = (data_packet_t *) malloc(sizeof(data_packet_t)); packet->header.magicnum = BT_MAGIC; packet->header.version = 1; packet->header.packet_type = 3; packet->header.header_len = sizeof(header_t); packet->header.header_len = sizeof(header_t); packet->header.packet_len = sizeof(header_t) + BT_PACKET_DATA_SIZE; packet->header.seq_num = i / BT_PACKET_DATA_SIZE; packet->data = malloc(BT_PACKET_DATA_SIZE); memcpy(packet->data, buf, BT_PACKET_DATA_SIZE); ctl_udp_send(&senders[sender_id], peer, packet); } return 0; }
static IceTImage vtreeCompose(void) { GLint rank, num_proc; GLint num_tiles; GLint max_pixels; GLint *display_nodes; GLint tile_displayed; GLboolean *all_contained_tmasks; GLint *tile_viewports; IceTImage imageBuffer; IceTSparseImage inImage, outImage; struct node_info *info; struct node_info *my_info; int tile, node; int tiles_transfered; int tile_held = -1; icetRaiseDebug("In vtreeCompose"); /* Get state. */ icetGetIntegerv(ICET_RANK, &rank); icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); icetGetIntegerv(ICET_NUM_TILES, &num_tiles); icetGetIntegerv(ICET_TILE_MAX_PIXELS, &max_pixels); display_nodes = icetUnsafeStateGet(ICET_DISPLAY_NODES); tile_viewports = icetUnsafeStateGet(ICET_TILE_VIEWPORTS); icetGetIntegerv(ICET_TILE_DISPLAYED, &tile_displayed); /* Allocate buffers. */ icetResizeBuffer( icetFullImageSize(max_pixels) + icetSparseImageSize(max_pixels)*2 + sizeof(struct node_info)*num_proc + sizeof(GLboolean)*num_proc*num_tiles); imageBuffer = icetReserveBufferMem(icetFullImageSize(max_pixels)); inImage = icetReserveBufferMem(icetSparseImageSize(max_pixels)); outImage = icetReserveBufferMem(icetSparseImageSize(max_pixels)); info = icetReserveBufferMem(sizeof(struct node_info)*num_proc); all_contained_tmasks = icetReserveBufferMem(sizeof(GLboolean)*num_proc*num_tiles); icetGetBooleanv(ICET_ALL_CONTAINED_TILES_MASKS, all_contained_tmasks); /* Initialize info array. */ for (node = 0; node < num_proc; node++) { info[node].rank = node; info[node].tile_held = -1; /* Id of tile image held in memory. */ info[node].num_contained = 0; /* # of images to be rendered. */ for (tile = 0; tile < num_tiles; tile++) { if (all_contained_tmasks[node*num_tiles + tile]) { info[node].num_contained++; } } } #define CONTAINS_TILE(nodei, tile) \ (all_contained_tmasks[info[nodei].rank*num_tiles+(tile)]) tile_held = -1; do { int recv_node; tiles_transfered = 0; sort_by_contained(info, num_proc); for (node = 0; node < num_proc; node++) { info[node].tile_sending = -1; info[node].tile_receiving = -1; } for (recv_node = 0; recv_node < num_proc; recv_node++) { struct node_info *recv_info = info + recv_node; if (recv_info->tile_receiving >= 0) continue; if (recv_info->tile_held >= 0) { /* This node is holding a tile. It must either send or receive this tile. */ if (find_sender(info, num_proc, recv_node, recv_info->tile_held, display_nodes[recv_info->tile_held], num_tiles, all_contained_tmasks)) { tiles_transfered = 1; continue; } /* Could not find a match for a sender, how about someone who can receive it? */ if ( (recv_info->tile_sending < 0) && (recv_info->rank != display_nodes[recv_info->tile_held]) && find_receiver(info, num_proc, recv_node, recv_info->tile_held, display_nodes[recv_info->tile_held], num_tiles, all_contained_tmasks) ) { tiles_transfered = 1; } else { /* Could not send or receive. Give up. */ continue; } } /* OK. Let's try to receive any tile that we still have. */ for (tile = 0; tile < num_tiles; tile++) { if ( ( !CONTAINS_TILE(recv_node, tile) && (display_nodes[tile] != recv_info->rank) ) || (recv_info->tile_sending == tile) ) continue; if (find_sender(info, num_proc, recv_node, tile, display_nodes[tile], num_tiles, all_contained_tmasks)) { tiles_transfered = 1; break; } } } /* Now that we figured out who is sending to who, do the actual send and receive. */ my_info = NULL; for (node = 0; node < num_proc; node++) { if (info[node].rank == rank) { my_info = info + node; break; } } do_send_receive(my_info, tile_held, max_pixels, num_tiles, tile_viewports, all_contained_tmasks, imageBuffer, inImage, outImage); tile_held = my_info->tile_held; } while (tiles_transfered); /* It's possible that a composited image ended up on a processor that */ /* is not the display node for that image. Do one last round of */ /* transfers to make sure all the tiles ended up in the right place. */ for (node = 0; node < num_proc; node++) { if (info[node].rank == rank) { my_info = info + node; break; } } my_info->tile_receiving = -1; my_info->tile_sending = -1; if ((my_info->tile_held >= 0) && (my_info->tile_held != tile_displayed)) { /* I'm holding an image that does not belong to me. Ship it off. */ my_info->tile_sending = my_info->tile_held; my_info->send_dest = display_nodes[my_info->tile_held]; my_info->tile_held = -1; } if ((my_info->tile_held != tile_displayed) && (tile_displayed >= 0)) { /* Someone may be holding an image that belongs to me. Check. */ for (node = 0; node < num_proc; node++) { if (info[node].tile_held == tile_displayed) { my_info->tile_receiving = tile_displayed; my_info->recv_src = info[node].rank; my_info->tile_held = tile_displayed; break; } } } do_send_receive(my_info, tile_held, max_pixels, num_tiles, tile_viewports, all_contained_tmasks, imageBuffer, inImage, outImage); tile_held = my_info->tile_held; /* Hacks for when "this" tile was not rendered. */ if ((tile_displayed >= 0) && (tile_displayed != tile_held)) { if (all_contained_tmasks[rank*num_tiles + tile_displayed]) { /* Only "this" node draws "this" tile. Because the image never */ /* needed to be transferred, it was never rendered above. Just */ /* render it now. */ icetRaiseDebug("Rendering tile to display."); /* This may uncessarily read a buffer if not outputing an input buffer */ icetGetTileImage(tile_displayed, imageBuffer); } else { /* "This" tile is blank. */ icetRaiseDebug("Returning blank image."); icetInitializeImage(imageBuffer, max_pixels); icetClearImage(imageBuffer); } } return imageBuffer; }