《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.1 KiB

12 years ago
  1. #include <defs.h>
  2. #include <string.h>
  3. #include <bitmap.h>
  4. #include <kmalloc.h>
  5. #include <error.h>
  6. #include <assert.h>
  7. #define WORD_TYPE uint32_t
  8. #define WORD_BITS (sizeof(WORD_TYPE) * CHAR_BIT)
  9. struct bitmap {
  10. uint32_t nbits;
  11. uint32_t nwords;
  12. WORD_TYPE *map;
  13. };
  14. // bitmap_create - allocate a new bitmap object.
  15. struct bitmap *
  16. bitmap_create(uint32_t nbits) {
  17. static_assert(WORD_BITS != 0);
  18. assert(nbits != 0 && nbits + WORD_BITS > nbits);
  19. struct bitmap *bitmap;
  20. if ((bitmap = kmalloc(sizeof(struct bitmap))) == NULL) {
  21. return NULL;
  22. }
  23. uint32_t nwords = ROUNDUP_DIV(nbits, WORD_BITS);
  24. WORD_TYPE *map;
  25. if ((map = kmalloc(sizeof(WORD_TYPE) * nwords)) == NULL) {
  26. kfree(bitmap);
  27. return NULL;
  28. }
  29. bitmap->nbits = nbits, bitmap->nwords = nwords;
  30. bitmap->map = memset(map, 0xFF, sizeof(WORD_TYPE) * nwords);
  31. /* mark any leftover bits at the end in use(0) */
  32. if (nbits != nwords * WORD_BITS) {
  33. uint32_t ix = nwords - 1, overbits = nbits - ix * WORD_BITS;
  34. assert(nbits / WORD_BITS == ix);
  35. assert(overbits > 0 && overbits < WORD_BITS);
  36. for (; overbits < WORD_BITS; overbits ++) {
  37. bitmap->map[ix] ^= (1 << overbits);
  38. }
  39. }
  40. return bitmap;
  41. }
  42. // bitmap_alloc - locate a cleared bit, set it, and return its index.
  43. int
  44. bitmap_alloc(struct bitmap *bitmap, uint32_t *index_store) {
  45. WORD_TYPE *map = bitmap->map;
  46. uint32_t ix, offset, nwords = bitmap->nwords;
  47. for (ix = 0; ix < nwords; ix ++) {
  48. if (map[ix] != 0) {
  49. for (offset = 0; offset < WORD_BITS; offset ++) {
  50. WORD_TYPE mask = (1 << offset);
  51. if (map[ix] & mask) {
  52. map[ix] ^= mask;
  53. *index_store = ix * WORD_BITS + offset;
  54. return 0;
  55. }
  56. }
  57. assert(0);
  58. }
  59. }
  60. return -E_NO_MEM;
  61. }
  62. // bitmap_translate - according index, get the related word and mask
  63. static void
  64. bitmap_translate(struct bitmap *bitmap, uint32_t index, WORD_TYPE **word, WORD_TYPE *mask) {
  65. assert(index < bitmap->nbits);
  66. uint32_t ix = index / WORD_BITS, offset = index % WORD_BITS;
  67. *word = bitmap->map + ix;
  68. *mask = (1 << offset);
  69. }
  70. // bitmap_test - according index, get the related value (0 OR 1) in the bitmap
  71. bool
  72. bitmap_test(struct bitmap *bitmap, uint32_t index) {
  73. WORD_TYPE *word, mask;
  74. bitmap_translate(bitmap, index, &word, &mask);
  75. return (*word & mask);
  76. }
  77. // bitmap_free - according index, set related bit to 1
  78. void
  79. bitmap_free(struct bitmap *bitmap, uint32_t index) {
  80. WORD_TYPE *word, mask;
  81. bitmap_translate(bitmap, index, &word, &mask);
  82. assert(!(*word & mask));
  83. *word |= mask;
  84. }
  85. // bitmap_destroy - free memory contains bitmap
  86. void
  87. bitmap_destroy(struct bitmap *bitmap) {
  88. kfree(bitmap->map);
  89. kfree(bitmap);
  90. }
  91. // bitmap_getdata - return bitmap->map, return the length of bits to len_store
  92. void *
  93. bitmap_getdata(struct bitmap *bitmap, size_t *len_store) {
  94. if (len_store != NULL) {
  95. *len_store = sizeof(WORD_TYPE) * bitmap->nwords;
  96. }
  97. return bitmap->map;
  98. }