/* 在pf表示的虚拟内存池中申请pg_cnt个虚拟页, * 成功则返回虚拟页的起始地址, 失败则返回NULL */ static void* vaddr_get(enum pool_flags pf, uint32_t pg_cnt) { int vaddr_start = 0, bit_idx_start = -1; uint32_t cnt = 0; if (pf == PF_KERNEL) { // 内核内存池 bit_idx_start = bitmap_scan(&kernel_vaddr.vaddr_bitmap, pg_cnt); if (bit_idx_start == -1) { return NULL; } while(cnt < pg_cnt) { bitmap_set(&kernel_vaddr.vaddr_bitmap, bit_idx_start + cnt++, 1); } vaddr_start = kernel_vaddr.vaddr_start + bit_idx_start * PG_SIZE; } else { // 用户内存池 struct task_struct* cur = running_thread(); bit_idx_start = bitmap_scan(&cur->userprog_vaddr.vaddr_bitmap, pg_cnt); if (bit_idx_start == -1) { return NULL; } while(cnt < pg_cnt) { bitmap_set(&cur->userprog_vaddr.vaddr_bitmap, bit_idx_start + cnt++, 1); } vaddr_start = cur->userprog_vaddr.vaddr_start + bit_idx_start * PG_SIZE; /* (0xc0000000 - PG_SIZE)做为用户3级栈已经在start_process被分配 */ ASSERT((uint32_t)vaddr_start < (0xc0000000 - PG_SIZE)); } return (void*)vaddr_start; }
//adds a page to swap space, gets called with the physical memory position size_t add_swap (void * addr) { //init swap if necessary if (swap == NULL) //init the swap table init_swap (); //lock the swap table lock_acquire(&swap_lock); //find a free entry in the bitmap table size_t free = bitmap_scan (swap_table, 0, 1, false); //if the swap table is full panic the kernel if (free == BITMAP_ERROR) PANIC ("Swaptable is full\n"); int i; //get frame and the memory position and write it to swap for (i = 0; i< SECPP; i++) //write block to swap, free * SECPP is the correct block position and + i because a page has a different size, same for addr block_write (swap, free * SECPP + i, addr + BLOCK_SECTOR_SIZE * i); //set the corresponding entry in the swap_table to true bitmap_set (swap_table, free, true); //release the lock for the swap table lock_release(&swap_lock); return free; }
/* 分配一个i结点,返回i结点号 */ int32_t inode_bitmap_alloc(struct partition* part) { int32_t bit_idx = bitmap_scan(&part->inode_bitmap, 1); if (bit_idx == -1) { return -1; } bitmap_set(&part->inode_bitmap, bit_idx, 1); return bit_idx; }
/* 分配1个扇区,返回其扇区地址 */ int32_t block_bitmap_alloc(struct partition* part) { int32_t bit_idx = bitmap_scan(&part->block_bitmap, 1); if (bit_idx == -1) { return -1; } bitmap_set(&part->block_bitmap, bit_idx, 1); /* 和inode_bitmap_malloc不同,此处返回的不是位图索引,而是具体可用的扇区地址 */ return (part->sb->data_start_lba + bit_idx); }
/* adds a block to cache */ static size_t cache_add (block_sector_t bid) { /* lock the cache */ lock_acquire(&cache_globallock); //bool hellYeah = bid == (unsigned) 163; /* lock for a free_cache_block cache block */ size_t free_cache_block = bitmap_scan (cache_table, 0, 1, false); //if(DEBUG || hellYeah) printf("bitscan complete bla\n"); /* if no free cache block is found, evict one and * search again */ if (free_cache_block == BITMAP_ERROR) { //if(DEBUG || hellYeah) printf("evict some\n"); cache_evict(); free_cache_block = bitmap_scan (cache_table, 0, 1, false); } ASSERT(free_cache_block != BITMAP_ERROR); //if(DEBUG || hellYeah) printf("add cache block %d\n",bid); /* copy block to cache */ block_read (fs_device, bid, cache[free_cache_block]->kpage); /* setup cache entry */ cache[free_cache_block]->dirty = false; cache[free_cache_block]->accessed = false; cache[free_cache_block]->bid = bid; /* set used bit of the cache table for this entry */ bitmap_set (cache_table, free_cache_block, true); /* release the lock for the cache table */ lock_release(&cache_globallock); if(CACHE_DEBUG) printf("added cache block %u for sector %u\n", (unsigned int) free_cache_block, (unsigned int) bid); return free_cache_block; }
size_t swap_out(void *kaddr) { lock_acquire(&swap_lock); //size_t free_index = bitmap_scan_and_flip(swap_map,0,1,SWAP_FREE); size_t free_index = bitmap_scan(swap_map,0,1,SWAP_FREE); bitmap_flip(swap_map,free_index); size_t i; for(i = 0;i <SECTORS_PER_PAGE;i++) { block_write(swap_block,free_index*SECTORS_PER_PAGE +i, (uint8_t*)kaddr + i*BLOCK_SECTOR_SIZE); } lock_release(&swap_lock); return free_index; }
/* 在pf表示的虚拟内存池中申请pg_cnt个虚拟页, * 成功则返回虚拟页的起始地址, 失败则返回NULL */ static void* vaddr_get(enum pool_flags pf, uint32_t pg_cnt) { int vaddr_start = 0, bit_idx_start = -1; uint32_t cnt = 0; if (pf == PF_KERNEL) { bit_idx_start = bitmap_scan(&kernel_vaddr.vaddr_bitmap, pg_cnt); if (bit_idx_start == -1) { return NULL; } while(cnt < pg_cnt) { bitmap_set(&kernel_vaddr.vaddr_bitmap, bit_idx_start + cnt++, 1); } vaddr_start = kernel_vaddr.vaddr_start + bit_idx_start * PG_SIZE; } else { // 用户内存池,将来实现用户进程再补充 } return (void*)vaddr_start; }
static void update_ct_zones(struct sset *lports, struct simap *ct_zones, unsigned long *ct_zone_bitmap) { struct simap_node *ct_zone, *ct_zone_next; const char *iface_id; int scan_start = 1; /* xxx This is wasteful to assign a zone to each port--even if no * xxx security policy is applied. */ /* Delete any zones that are associated with removed ports. */ SIMAP_FOR_EACH_SAFE(ct_zone, ct_zone_next, ct_zones) { if (!sset_contains(lports, ct_zone->name)) { bitmap_set0(ct_zone_bitmap, ct_zone->data); simap_delete(ct_zones, ct_zone); } } /* Assign a unique zone id for each logical port. */ SSET_FOR_EACH(iface_id, lports) { size_t zone; if (simap_contains(ct_zones, iface_id)) { continue; } /* We assume that there are 64K zones and that we own them all. */ zone = bitmap_scan(ct_zone_bitmap, 0, scan_start, MAX_CT_ZONES + 1); if (zone == MAX_CT_ZONES + 1) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_WARN_RL(&rl, "exhausted all ct zones"); return; } scan_start = zone + 1; bitmap_set1(ct_zone_bitmap, zone); simap_put(ct_zones, iface_id, zone); /* xxx We should erase any old entries for this * xxx zone, but we need a generic interface to the conntrack * xxx table. */ }
uint32 bitmap_scan_and_set (struct bitmap* bmap, uint32 num) { if (bmap == NULL || num == 0) return BITMAP_ERROR; uint32 idx = bitmap_scan (bmap, num); if (idx == BITMAP_ERROR) return idx; uint32 i; uint32 end = idx + num; for (i = idx; i < end; i++) bitmap_set (bmap, i); return idx; // // uint32 i; // for (i = 0; i < bmap->length; i++) // { // if (bmap->bits[i] != 0xFFFFFFFF) // { // sint32 j; // bool one = false; // uint32 count = 0; // sint32 idx = 0; // for (j = 31; j >= 0; j--) // { // if (!(bmap->bits[i] & (uint32) (0x1 << j))) // { // if (!one) // { // idx = j; // count = 0; // } // count++; // one = true; // } // else // one = false; // // if (count == num) // break; // } // // ASSERT (count <= num); // ASSERT (idx < 32); // if (count == num) // { // /* We must flip NUM contiguous bits. */ // sint32 k; // for (k = idx; k > (sint32) (idx - num); k--) // { // bmap->bits[i] |= (uint32) (0x1 << k); // } // // return i * 32 + (31 - idx); // } // } // } // // return BITMAP_ERROR; };