|
|
1.1 ! root 1: ! 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 Microsoft Corporation. ! 5: * All rights reserved. ! 6: * This source code is only intended as a supplement to ! 7: * Microsoft Development Tools and/or WinHelp documentation. ! 8: * See these sources for detailed information regarding the ! 9: * Microsoft samples programs. ! 10: \******************************************************************************/ ! 11: ! 12: /****************************** Module Header ******************************* ! 13: * Module Name: GBIT.C ! 14: * ! 15: * Bitmap allocation routines to manage a bit-mapped free list, and find ! 16: * free sections. ! 17: * ! 18: * Functions: ! 19: * ! 20: * gbit_set() ! 21: * gbit_init() ! 22: * gbit_alloc() ! 23: * gbit_free() ! 24: * gbit_findfree() ! 25: * ! 26: * Comments: ! 27: * ! 28: * Each map is an array of unsigned longs where bit 0 of the first ! 29: * long represents block 1. ! 30: * ! 31: ****************************************************************************/ ! 32: ! 33: #include <windows.h> ! 34: #include "gutils.h" ! 35: ! 36: ! 37: BOOL gbit_set(DWORD FAR * map, long blknr, long nblks, BOOL op_set); ! 38: ! 39: /*************************************************************************** ! 40: * Function: gbit_init ! 41: * ! 42: * Purpose: ! 43: * ! 44: * Initialise a pre-allocated map of ulongs to represent a free ! 45: * area of nblks ! 46: */ ! 47: void APIENTRY ! 48: gbit_init(DWORD FAR * map, long nblks) ! 49: { ! 50: long i; ! 51: long leftover = nblks % 32; ! 52: long blks = nblks / 32; ! 53: DWORD last = 0; ! 54: ! 55: for (i=0; i < blks; i++) { ! 56: map[i] = 0xffffffff; ! 57: } ! 58: for (i = 0; i < leftover; i++) { ! 59: last = (last << 1) | 1; ! 60: } ! 61: if(leftover) ! 62: map[blks] = last; ! 63: } ! 64: ! 65: /*************************************************************************** ! 66: * Function: gbit_alloc ! 67: * ! 68: * Purpose: ! 69: * ! 70: * Mark a region starting at blknr for nblks, as busy (ie 0) ! 71: */ ! 72: BOOL APIENTRY ! 73: gbit_alloc(DWORD FAR * map, long blknr, long nblks) ! 74: { ! 75: return(gbit_set(map, blknr, nblks, FALSE)); ! 76: } ! 77: ! 78: ! 79: /*************************************************************************** ! 80: * Function: gbit_set ! 81: * ! 82: * Purpose: ! 83: * ! 84: * Mark region - if op_set, to 1s, otherwise to 0s ! 85: */ ! 86: BOOL ! 87: gbit_set(DWORD FAR * map, long blknr, long nblks, BOOL op_set) ! 88: { ! 89: long first; ! 90: long last; ! 91: long fullwords; ! 92: long startbit, startword; ! 93: long i; ! 94: DWORD dword = 0; ! 95: ! 96: blknr--; ! 97: first = min(32 - (blknr % 32), nblks); ! 98: nblks -= first; ! 99: last = nblks % 32; ! 100: fullwords = (nblks - last) / 32; ! 101: ! 102: startword = blknr / 32; ! 103: startbit = blknr % 32; ! 104: for (i = 0; i < first; i++) { ! 105: dword = (dword << 1) | 1; ! 106: } ! 107: dword <<= startbit; ! 108: if (op_set) { ! 109: map[startword] |= dword; ! 110: dword = 0xffffffff; ! 111: } else { ! 112: map[startword] &= ~dword; ! 113: dword = 0; ! 114: } ! 115: startword++; ! 116: for (i = 0; i < fullwords; i++) { ! 117: map[startword+i] = dword; ! 118: } ! 119: startword += fullwords; ! 120: for(i = 0, dword = 0; i < last; i++) { ! 121: dword = (dword << 1) | 1; ! 122: } ! 123: if (last) { ! 124: if (op_set) { ! 125: map[startword] |= dword; ! 126: } else { ! 127: map[startword] &= ~dword; ! 128: } ! 129: } ! 130: ! 131: return(TRUE); ! 132: } ! 133: ! 134: /*************************************************************************** ! 135: * Function: gbit_free ! 136: * ! 137: * Purpose: ! 138: * ! 139: * Mark region of nblks starting at blknr to 0s - ie not busy ! 140: */ ! 141: BOOL APIENTRY ! 142: gbit_free(DWORD FAR * map, long blknr, long nblks) ! 143: { ! 144: return(gbit_set(map, blknr, nblks, TRUE)); ! 145: } ! 146: ! 147: ! 148: /*************************************************************************** ! 149: * Function: gbit_findfree ! 150: * ! 151: * Purpose: ! 152: * ! 153: * Find a free segment (ie contiguous sequence of 1s) of nblks in length. ! 154: * If not found, find longest sequence. Store address of segment in *blknr. ! 155: * ! 156: * Return value is nr of blks in sequence found. Region is *not* marked busy. ! 157: */ ! 158: long APIENTRY ! 159: gbit_findfree(DWORD FAR* map, long nblks, long mapsize, long FAR * blknr) ! 160: { ! 161: long curblk, startblk, len, i; ! 162: long startbit, nfull, nlast, nbitsleft; ! 163: DWORD mask; ! 164: long mapblks = (mapsize + 31) / 32; ! 165: long aubegin = 0, aulen = 0; ! 166: long curbit = 0; ! 167: ! 168: /* main loop looking at segments */ ! 169: for (curblk = 0; curblk < mapblks; ) { ! 170: loop: ! 171: /* loop finding first 1 */ ! 172: for (; curblk < mapblks; curblk++, curbit = 0) { ! 173: if (map[curblk] > 0) { ! 174: break; ! 175: } ! 176: } ! 177: if (curblk >= mapblks) ! 178: break; ! 179: ! 180: /* find first 1 in this long */ ! 181: startblk = curblk; ! 182: for (mask = 1, i = 0; i < curbit; i++) { ! 183: mask <<= 1; ! 184: } ! 185: for(; curbit < 32; curbit++, mask <<= 1) { ! 186: if (map[curblk] & mask) { ! 187: break; ! 188: } ! 189: } ! 190: if (curbit >= 32) { ! 191: /* abandon this word - start again with next word */ ! 192: curblk++; ! 193: curbit = 0; ! 194: goto loop; ! 195: } ! 196: ! 197: /* we've now found a 1 - calc remaining ! 198: * bits in this word, complete words etc required. ! 199: */ ! 200: startbit = curbit; ! 201: nbitsleft = min( (32 - curbit), nblks); ! 202: nfull = (nblks - nbitsleft) / 32; ! 203: nlast = (nblks - nbitsleft) % 32; ! 204: ! 205: /* check for required sequence within this word */ ! 206: ! 207: for (i = 0; i < nbitsleft; i++, curbit++, mask <<= 1) { ! 208: if ((map[curblk] & mask) == 0) { ! 209: /* abandon and start again - start ! 210: * next pass at curbit in same word ! 211: */ ! 212: /* store free region if longest yet */ ! 213: if (i > aulen) { ! 214: aulen = i; ! 215: aubegin = curblk * 32 + startbit +1; ! 216: } ! 217: goto loop; ! 218: } ! 219: } ! 220: ! 221: /* check for nfull full words */ ! 222: for (curblk++; curblk <= startblk + nfull; curblk++) { ! 223: if (curblk >= mapblks) { ! 224: /* end of map - abandon here and exit at top ! 225: * of loop ! 226: */ ! 227: len = nbitsleft + ! 228: ((curblk - (startblk + 1)) * 32); ! 229: if (len > aulen) { ! 230: aubegin = startblk * 32 + startbit + 1; ! 231: aulen = len; ! 232: } ! 233: goto loop; ! 234: } ! 235: if (map[curblk] != 0xffffffff) { ! 236: /* not a full word - start again at this bit */ ! 237: len = 0; ! 238: curbit = 0; ! 239: for (mask = 1; mask & map[curblk]; mask <<= 1) { ! 240: len++; ! 241: curbit++; ! 242: } ! 243: len += nbitsleft + ! 244: (curblk - (startblk+ 1)) * 32; ! 245: if (len > aulen) { ! 246: aulen = len; ! 247: aubegin = startblk * 32 + startbit + 1; ! 248: } ! 249: /* continue with current blk, bit */ ! 250: goto loop; ! 251: } ! 252: } ! 253: ! 254: /* left-over bits required in last word */ ! 255: mask = 1; ! 256: for (curbit = 0; curbit < nlast; curbit++, mask <<= 1) { ! 257: if ((map[curblk] & mask) == 0) { ! 258: len = nbitsleft + (nfull * 32); ! 259: len += curbit; ! 260: if (len > aulen) { ! 261: aulen = len; ! 262: aubegin = startblk * 32 + startbit + 1; ! 263: } ! 264: goto loop; ! 265: } ! 266: } ! 267: /* ok - found a block big enough! */ ! 268: aubegin = startblk * 32 + startbit + 1; ! 269: *blknr = aubegin; ! 270: return(nblks); ! 271: } ! 272: ! 273: /* end of map - return longest sequence */ ! 274: *blknr = aubegin; ! 275: return(aulen); ! 276: } ! 277: ! 278:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.