PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/uClinux-dist/user/squid/src/filemap.c

https://github.com/labx-technologies-llc/mb-linux-labx
C | 172 lines | 114 code | 15 blank | 43 comment | 12 complexity | b0f8d8c5edc85a2b9b25797d3646b098 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception, ISC, AGPL-1.0, LGPL-2.0, GPL-3.0, LGPL-3.0, 0BSD
  1. /*
  2. * $Id: filemap.c,v 1.39 2001/10/24 07:45:34 hno Exp $
  3. *
  4. * DEBUG: section 8 Swap File Bitmap
  5. * AUTHOR: Harvest Derived
  6. *
  7. * SQUID Web Proxy Cache http://www.squid-cache.org/
  8. * ----------------------------------------------------------
  9. *
  10. * Squid is the result of efforts by numerous individuals from
  11. * the Internet community; see the CONTRIBUTORS file for full
  12. * details. Many organizations have provided support for Squid's
  13. * development; see the SPONSORS file for full details. Squid is
  14. * Copyrighted (C) 2001 by the Regents of the University of
  15. * California; see the COPYRIGHT file for full details. Squid
  16. * incorporates software developed and/or copyrighted by other
  17. * sources; see the CREDITS file for full details.
  18. *
  19. * This program is free software; you can redistribute it and/or modify
  20. * it under the terms of the GNU General Public License as published by
  21. * the Free Software Foundation; either version 2 of the License, or
  22. * (at your option) any later version.
  23. *
  24. * This program is distributed in the hope that it will be useful,
  25. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. * GNU General Public License for more details.
  28. *
  29. * You should have received a copy of the GNU General Public License
  30. * along with this program; if not, write to the Free Software
  31. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  32. *
  33. */
  34. #include "squid.h"
  35. /* Number of bits in a long */
  36. #if SIZEOF_LONG == 8
  37. #define LONG_BIT_SHIFT 6
  38. #define BITS_IN_A_LONG 0x40
  39. #define LONG_BIT_MASK 0x3F
  40. #define ALL_ONES (unsigned long) 0xFFFFFFFFFFFFFFFF
  41. #elif SIZEOF_LONG == 4
  42. #define LONG_BIT_SHIFT 5
  43. #define BITS_IN_A_LONG 0x20
  44. #define LONG_BIT_MASK 0x1F
  45. #define ALL_ONES (unsigned long) 0xFFFFFFFF
  46. #else
  47. #define LONG_BIT_SHIFT 5
  48. #define BITS_IN_A_LONG 0x20
  49. #define LONG_BIT_MASK 0x1F
  50. #define ALL_ONES (unsigned long) 0xFFFFFFFF
  51. #endif
  52. #define FM_INITIAL_NUMBER (1<<14)
  53. fileMap *
  54. file_map_create(void)
  55. {
  56. fileMap *fm = xcalloc(1, sizeof(fileMap));
  57. fm->max_n_files = FM_INITIAL_NUMBER;
  58. fm->nwords = fm->max_n_files >> LONG_BIT_SHIFT;
  59. debug(8, 3) ("file_map_create: creating space for %d files\n", fm->max_n_files);
  60. debug(8, 5) ("--> %d words of %d bytes each\n",
  61. fm->nwords, (int) sizeof(*fm->file_map));
  62. fm->file_map = xcalloc(fm->nwords, sizeof(*fm->file_map));
  63. /* XXX account fm->file_map */
  64. return fm;
  65. }
  66. static void
  67. file_map_grow(fileMap * fm)
  68. {
  69. int old_sz = fm->nwords * sizeof(*fm->file_map);
  70. void *old_map = fm->file_map;
  71. fm->max_n_files <<= 1;
  72. assert(fm->max_n_files <= (1 << 24)); /* swap_filen is 25 bits, signed */
  73. fm->nwords = fm->max_n_files >> LONG_BIT_SHIFT;
  74. debug(8, 3) ("file_map_grow: creating space for %d files\n", fm->max_n_files);
  75. fm->file_map = xcalloc(fm->nwords, sizeof(*fm->file_map));
  76. debug(8, 3) ("copying %d old bytes\n", old_sz);
  77. xmemcpy(fm->file_map, old_map, old_sz);
  78. xfree(old_map);
  79. /* XXX account fm->file_map */
  80. }
  81. int
  82. file_map_bit_set(fileMap * fm, int file_number)
  83. {
  84. unsigned long bitmask = (1L << (file_number & LONG_BIT_MASK));
  85. while (file_number >= fm->max_n_files)
  86. file_map_grow(fm);
  87. fm->file_map[file_number >> LONG_BIT_SHIFT] |= bitmask;
  88. fm->n_files_in_map++;
  89. return file_number;
  90. }
  91. /*
  92. * WARNING: file_map_bit_reset does not perform array bounds
  93. * checking! It assumes that 'file_number' is valid, and that the
  94. * bit is already set. The caller must verify both of those
  95. * conditions by calling file_map_bit_test() first.
  96. */
  97. void
  98. file_map_bit_reset(fileMap * fm, int file_number)
  99. {
  100. unsigned long bitmask = (1L << (file_number & LONG_BIT_MASK));
  101. fm->file_map[file_number >> LONG_BIT_SHIFT] &= ~bitmask;
  102. fm->n_files_in_map--;
  103. }
  104. int
  105. file_map_bit_test(fileMap * fm, int file_number)
  106. {
  107. unsigned long bitmask = (1L << (file_number & LONG_BIT_MASK));
  108. if (file_number >= fm->max_n_files)
  109. return 0;
  110. /* be sure the return value is an int, not a u_long */
  111. return (fm->file_map[file_number >> LONG_BIT_SHIFT] & bitmask ? 1 : 0);
  112. }
  113. int
  114. file_map_allocate(fileMap * fm, int suggestion)
  115. {
  116. int word;
  117. int bit;
  118. int count;
  119. if (suggestion >= fm->max_n_files)
  120. suggestion = 0;
  121. if (!file_map_bit_test(fm, suggestion))
  122. return suggestion;
  123. word = suggestion >> LONG_BIT_SHIFT;
  124. for (count = 0; count < fm->nwords; count++) {
  125. if (fm->file_map[word] != ALL_ONES)
  126. break;
  127. word = (word + 1) % fm->nwords;
  128. }
  129. for (bit = 0; bit < BITS_IN_A_LONG; bit++) {
  130. suggestion = ((unsigned long) word << LONG_BIT_SHIFT) | bit;
  131. if (!file_map_bit_test(fm, suggestion)) {
  132. return suggestion;
  133. }
  134. }
  135. debug(8, 3) ("growing from file_map_allocate\n");
  136. file_map_grow(fm);
  137. return file_map_allocate(fm, fm->max_n_files >> 1);
  138. }
  139. void
  140. filemapFreeMemory(fileMap * fm)
  141. {
  142. safe_free(fm->file_map);
  143. safe_free(fm);
  144. }
  145. #ifdef TEST
  146. #define TEST_SIZE 1<<16
  147. main(argc, argv)
  148. {
  149. int i;
  150. fm = file_map_create(TEST_SIZE);
  151. for (i = 0; i < TEST_SIZE; ++i) {
  152. file_map_bit_set(i);
  153. assert(file_map_bit_test(i));
  154. file_map_bit_reset(i);
  155. }
  156. }
  157. #endif