1 /* 2 * Copyright (C) 2007 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <errno.h> 22 #include <gpxe/bitmap.h> 23 24 /** @file 25 * 26 * Bitmaps for multicast downloads 27 * 28 */ 29 30 /** 31 * Resize bitmap 32 * 33 * @v bitmap Bitmap 34 * @v new_length New length of bitmap, in bits 35 * @ret rc Return status code 36 */ 37 int bitmap_resize ( struct bitmap *bitmap, unsigned int new_length ) { 38 unsigned int old_num_blocks; 39 unsigned int new_num_blocks; 40 size_t new_size; 41 bitmap_block_t *new_blocks; 42 43 old_num_blocks = BITMAP_INDEX ( bitmap->length + BITMAP_BLKSIZE - 1 ); 44 new_num_blocks = BITMAP_INDEX ( new_length + BITMAP_BLKSIZE - 1 ); 45 46 if ( old_num_blocks != new_num_blocks ) { 47 new_size = ( new_num_blocks * sizeof ( bitmap->blocks[0] ) ); 48 new_blocks = realloc ( bitmap->blocks, new_size ); 49 if ( ! new_blocks ) { 50 DBGC ( bitmap, "Bitmap %p could not resize to %d " 51 "bits\n", bitmap, new_length ); 52 return -ENOMEM; 53 } 54 bitmap->blocks = new_blocks; 55 } 56 bitmap->length = new_length; 57 58 while ( old_num_blocks < new_num_blocks ) { 59 bitmap->blocks[old_num_blocks++] = 0; 60 } 61 62 DBGC ( bitmap, "Bitmap %p resized to %d bits\n", bitmap, new_length ); 63 return 0; 64 } 65 66 /** 67 * Test bit in bitmap 68 * 69 * @v bitmap Bitmap 70 * @v bit Bit index 71 * @ret is_set Bit is set 72 */ 73 int bitmap_test ( struct bitmap *bitmap, unsigned int bit ) { 74 unsigned int index = BITMAP_INDEX ( bit ); 75 bitmap_block_t mask = BITMAP_MASK ( bit ); 76 77 if ( bit >= bitmap->length ) 78 return 0; 79 return ( bitmap->blocks[index] & mask ); 80 } 81 82 /** 83 * Set bit in bitmap 84 * 85 * @v bitmap Bitmap 86 * @v bit Bit index 87 */ 88 void bitmap_set ( struct bitmap *bitmap, unsigned int bit ) { 89 unsigned int index = BITMAP_INDEX ( bit ); 90 bitmap_block_t mask = BITMAP_MASK ( bit ); 91 92 DBGC ( bitmap, "Bitmap %p setting bit %d\n", bitmap, bit ); 93 94 /* Update bitmap */ 95 bitmap->blocks[index] |= mask; 96 97 /* Update first gap counter */ 98 while ( bitmap_test ( bitmap, bitmap->first_gap ) ) { 99 bitmap->first_gap++; 100 } 101 } 102