bitmap.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00040 #include <adt/bitmap.h>
00041 #include <typedefs.h>
00042 #include <arch/types.h>
00043 #include <align.h>
00044 #include <debug.h>
00045 #include <macros.h>
00046 
00047 #define ALL_ONES        0xff
00048 #define ALL_ZEROES      0x00
00049 
00058 void bitmap_initialize(bitmap_t *bitmap, __u8 *map, count_t bits)
00059 {
00060         bitmap->map = map;
00061         bitmap->bits = bits;
00062 }
00063 
00070 void bitmap_set_range(bitmap_t *bitmap, index_t start, count_t bits)
00071 {
00072         index_t i=0;
00073         index_t aligned_start;
00074         count_t lub;            /* leading unaligned bits */
00075         count_t amb;            /* aligned middle bits */
00076         count_t tab;            /* trailing aligned bits */
00077         
00078         ASSERT(start + bits <= bitmap->bits);
00079         
00080         aligned_start = ALIGN_UP(start, 8);
00081         lub = min(aligned_start - start, bits);
00082         amb = bits > lub ? bits - lub : 0;
00083         tab = amb % 8;
00084         
00085         if ( start + bits < aligned_start ) {
00086             /*
00087             * Set bits in the middle of byte
00088             */
00089             bitmap->map[start / 8] |= ((1 << lub)-1) << (start&7);
00090             return;
00091         }
00092         
00093         if (lub) {
00094                 /*
00095                  * Make sure to set any leading unaligned bits.
00096                  */
00097                 bitmap->map[start / 8] |= ~((1 << (8 - lub)) - 1);
00098         }
00099         for (i = 0; i < amb / 8; i++) {
00100                 /*
00101                  * The middle bits can be set byte by byte.
00102                  */
00103                 bitmap->map[aligned_start / 8 + i] = ALL_ONES;
00104         }
00105         if (tab) {
00106                 /*
00107                  * Make sure to set any trailing aligned bits.
00108                  */
00109                 bitmap->map[aligned_start / 8 + i] |= (1 << tab) - 1;
00110         }
00111         
00112 }
00113 
00120 void bitmap_clear_range(bitmap_t *bitmap, index_t start, count_t bits)
00121 {
00122         index_t i=0;
00123         index_t aligned_start;
00124         count_t lub;            /* leading unaligned bits */
00125         count_t amb;            /* aligned middle bits */
00126         count_t tab;            /* trailing aligned bits */
00127         
00128         ASSERT(start + bits <= bitmap->bits);
00129         
00130         aligned_start = ALIGN_UP(start, 8);
00131         lub = min(aligned_start - start, bits);
00132         amb = bits > lub ? bits - lub : 0;
00133         tab = amb % 8;
00134 
00135         if ( start + bits < aligned_start )
00136         {
00137             /*
00138             * Set bits in the middle of byte
00139             */
00140             bitmap->map[start / 8] &= ~(((1 << lub)-1) << (start&7));
00141             return;
00142         }
00143 
00144 
00145         if (lub) {
00146                 /*
00147                  * Make sure to clear any leading unaligned bits.
00148                  */
00149                 bitmap->map[start / 8] &= (1 << (8 - lub)) - 1;
00150         }
00151         for (i = 0; i < amb / 8; i++) {
00152                 /*
00153                  * The middle bits can be cleared byte by byte.
00154                  */
00155                 bitmap->map[aligned_start / 8 + i] = ALL_ZEROES;
00156         }
00157         if (tab) {
00158                 /*
00159                  * Make sure to clear any trailing aligned bits.
00160                  */
00161                 bitmap->map[aligned_start / 8 + i] &= ~((1 << tab) - 1);
00162         }
00163 
00164 }
00165 
00172 void bitmap_copy(bitmap_t *dst, bitmap_t *src, count_t bits)
00173 {
00174         index_t i;
00175         
00176         ASSERT(bits <= dst->bits);
00177         ASSERT(bits <= src->bits);
00178         
00179         for (i = 0; i < bits / 8; i++)
00180                 dst->map[i] = src->map[i];
00181         
00182         if (bits % 8) {
00183                 bitmap_clear_range(dst, i * 8, bits % 8);
00184                 dst->map[i] |= src->map[i] & ((1 << (bits % 8)) - 1);
00185         }
00186 }
00187 

Generated on Sun Jun 18 16:26:57 2006 for HelenOS Kernel (amd64) by  doxygen 1.4.6