~cypheon/xos

xos/bitmap.c -rw-r--r-- 1.8 KiB
567db604 — Johann Rudloff Implement scanning and allocation of physical memory. 7 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <sys/bitmap.h>
#include <sys/types.h>
#include <stdlib.h>

struct bitmap *
bitmap_create(void *mem, uint32_t available, size_t bitmap_size) {
  /* check, if it fits */
  if (available < bitmap_required_size(bitmap_size)) {
    return NULL;
  }

  struct bitmap *bm = (struct bitmap *)mem;
  bm->size = bitmap_size;
  bm->first_clear = 0;
  bm->area = (uint32_t *)(mem + sizeof(struct bitmap *));

  memset(bm->area, 0, ((bitmap_size + 31) / 32) * 4);

  return NULL;
}

void
bitmap_set(struct bitmap *bm, uint32_t index) {
  uint32_t area_index = index / 32;
  uint32_t mask = 1 << (index % 32);
  bm->area[area_index] |= mask;
}

void
bitmap_clear(struct bitmap *bm, uint32_t index) {
  uint32_t area_index = index / 32;
  uint32_t mask = ~(1 << (index % 32));
  bm->area[area_index] &= mask;
  if (area_index < bm->first_clear) {
    bm->first_clear = area_index;
  }
}

int
bitmap_get(struct bitmap *bm, uint32_t index) {
  uint32_t area_index = index / 32;
  uint32_t mask = 1 << (index % 32);
  return (bm->area[area_index] & mask);
}

uint32_t
bitmap_find_clear(struct bitmap *bm) {
  for(uint32_t area_index = bm->first_clear; area_index < bm->size; ++area_index) {
    if (bm->area[area_index] != 0xffffffff) {
      area_index *= 32;
      uint32_t value = bm->area[area_index];
      while (value & 1) {
        area_index++;
        value >>= 1;
      }
      return area_index;
    }
  }

  return 0;
}

void
bitmap_range_update(struct bitmap *bm, uint32_t start, uint32_t count, int value) {
  // TODO: this is a very naive implementation, replace with a real one
  if (value) {
    for (uint32_t index=start; index<start+count; ++index) {
      bitmap_set(bm, index);
    }
  } else {
    for (uint32_t index=start; index<start+count; ++index) {
      bitmap_clear(bm, index);
    }
  }
}