// size in words. // Flag one means block is free. void initialiseFreeBlock(void* freeRegion, uint32_t size, void* prevFreeRegion, void* nextFreeRegion, bool flag, bool setHeader) { totalFreeSpace += WORDS_TO_BYTES(size); // Stats // Update largest free region. if (size > largestFreeBlock) { largestFreeBlock = WORDS_TO_BYTES(size); } if (setHeader) { struct blockHeader *header = INIT_STRUCT(blockHeader, freeRegion); header->attribute = size; // Set size. Size is max 2^30. Flag is 0 by default. if (flag) header->attribute |= MSB_TO_ONE; // Set flag to 1. } void* usableArea = ADDRESS_PLUS_OFFSET(freeRegion, blockHeader); struct freeBlockLinks *blockLinks = INIT_STRUCT(freeBlockLinks, usableArea); PREV_BLOCK(blockLinks) = prevFreeRegion; NEXT_BLOCK(blockLinks) = nextFreeRegion; // Set footer free region. uint64_t sizeOffset = WORDS_TO_BYTES(size); void* footer = ADDRESS_MINUS_OFFSET(usableArea + sizeOffset, freeBlockFooter); struct freeBlockFooter *blockFooter = INIT_STRUCT(freeBlockFooter, footer); blockFooter->size = size; }
void coalesceWithNextBlock(void* newAddr, uint32_t newSize, struct freeBlockLinks *successorBlockLinks) { struct blockHeader *newBlock = newAddr; newBlock->attribute = newSize; // Update links to freenodes. void* blockLinks = ADDRESS_PLUS_OFFSET(newAddr, blockHeader); struct freeBlockLinks *newBlockLinks = INIT_STRUCT(freeBlockLinks, blockLinks); PREV_BLOCK(newBlockLinks) = PREV_BLOCK(successorBlockLinks); NEXT_BLOCK(newBlockLinks) = NEXT_BLOCK(successorBlockLinks); // Prev block. void* prevLinks = ADDRESS_PLUS_OFFSET(PREV_BLOCK(newBlockLinks), blockHeader); struct freeBlockLinks *prevBlockLinks = INIT_STRUCT(freeBlockLinks, prevLinks); NEXT_BLOCK(prevBlockLinks) = newAddr; // Next block. void* nextLinks = ADDRESS_PLUS_OFFSET(NEXT_BLOCK(newBlockLinks), blockHeader); struct freeBlockLinks *nextBlockLinks = INIT_STRUCT(freeBlockLinks, nextLinks); PREV_BLOCK(prevBlockLinks) = newAddr; uint64_t sizeOffset = WORDS_TO_BYTES(newSize); setFooterBlockOnCoalescing(newAddr, sizeOffset, newSize); updateNextBlockOnCoalescing(newAddr, sizeOffset); }
// Remove allocated block from free list. void removeAllocatedBlock(struct freeBlockLinks *blockToBeRemovedLinks) { void* prevBlock = PREV_BLOCK(blockToBeRemovedLinks); void* prevLinks = ADDRESS_PLUS_OFFSET(prevBlock, blockHeader); struct freeBlockLinks *prevBlockLinks = INIT_STRUCT(freeBlockLinks, prevLinks); NEXT_BLOCK(prevBlockLinks) = NEXT_BLOCK(blockToBeRemovedLinks); void* nextBlock = NEXT_BLOCK(blockToBeRemovedLinks); void* nextLinks = ADDRESS_PLUS_OFFSET(nextBlock, blockHeader); struct freeBlockLinks *nextBlockLinks = INIT_STRUCT(freeBlockLinks, nextLinks); PREV_BLOCK(nextBlockLinks) = PREV_BLOCK(blockToBeRemovedLinks); }
// Insert new free block into the free list void insertFreeBlock(void* newBlock, struct freeBlockLinks *prevBlockLinks) { void* usableArea = ADDRESS_PLUS_OFFSET(newBlock, blockHeader); struct freeBlockLinks *newBlockLinks = INIT_STRUCT(freeBlockLinks, usableArea); void* next = NEXT_BLOCK(newBlockLinks) + sizeof(blockHeader); struct freeBlockLinks *nextBlock = INIT_STRUCT(freeBlockLinks, next); PREV_BLOCK(nextBlock) = newBlock; void* prev = PREV_BLOCK(newBlockLinks) + sizeof(blockHeader); struct freeBlockLinks *prevBlock = INIT_STRUCT(freeBlockLinks, prev); NEXT_BLOCK(prevBlock) = newBlock; }
void updateNextBlockOnCoalescing(void* newAddr, uint64_t sizeOffset) { // Next block void* nextBlock = ADDRESS_PLUS_OFFSET(newAddr + sizeOffset, blockHeader); struct blockHeader *nextBlockHeader = INIT_STRUCT(blockHeader, nextBlock); nextBlockHeader->attribute |= MSB_TO_ONE; // works for all blocks (also for mmap footer) }
// Split a large block into two sub-blocks. // spaceLeft and size are in words void *splitFreeBlock(void* blockToSplit, uint64_t spaceLeft, uint32_t size, void* currentFreeBlock, struct freeBlockLinks *currentBlockLinks) { // Reinitialise header of first sub-block. void* block = ADDRESS_MINUS_OFFSET(blockToSplit, blockHeader); struct blockHeader *allocatedBlock = INIT_STRUCT(blockHeader, block); allocatedBlock->attribute = size; // Create and initialise new node. uint32_t sizeNewNode = spaceLeft - BYTES_TO_WORDS(sizeof(blockHeader)); uint64_t sizeOffset = WORDS_TO_BYTES(size); void* endUserRequestedBlock = blockToSplit + sizeOffset; // initialise new block. void* prevBlock = PREV_BLOCK(currentBlockLinks); totalFreeSpace -= WORDS_TO_BYTES(spaceLeft); totalFreeSpace -= WORDS_TO_BYTES(size); // Stats initialiseFreeBlock(endUserRequestedBlock, sizeNewNode, prevBlock, currentFreeBlock, false, true); insertFreeBlock(endUserRequestedBlock, currentBlockLinks); return endUserRequestedBlock; }
// Lenght in bytes void setMmapFooter(void* newMmapRegion, uint64_t length) { // Footer Mmap region - Flag (0) + size (0) to indicate end region (same struct than block header) void* footer = ADDRESS_MINUS_OFFSET((newMmapRegion + length), blockHeader); struct blockHeader *footerMmap = INIT_STRUCT(blockHeader, footer); footerMmap->attribute = MSB_TO_ONE; // Previous region is free. }
// // EV_ActivateSpecialLineWithSpac // // Populates the ev_instance_t from separate arguments and then activates the // special. // bool EV_ActivateSpecialLineWithSpac(line_t *line, int side, Mobj *thing, int spac) { ev_action_t *action; INIT_STRUCT(ev_instance_t, instance); // setup instance instance.actor = thing; instance.args = line->args; instance.line = line; instance.special = line->special; instance.side = side; instance.spac = spac; instance.tag = line->args[0]; // get action if(!(action = EV_ActionForInstance(instance))) return false; // check for parameterized special behavior with tags if(EV_CompositeActionFlags(action) & EV_PARAMLINESPEC) instance.tag = instance.args[0]; // check for special instance if(!EV_checkSpac(action, &instance)) return false; return !!EV_ActivateSpecial(action, &instance); }
void setFooterBlockOnCoalescing(void* newAddr, uint64_t sizeOffset, uint32_t newSize) { // Footer void* footerAddr = newAddr + sizeof(blockHeader) + sizeOffset - sizeof(freeBlockFooter); struct freeBlockFooter *footer = INIT_STRUCT(freeBlockFooter, footerAddr); footer->size = newSize; }
// lengthMmapRegion in bytes bool coalesceMmapRegions(void* mmapsList, void* newMmapRegion, uint64_t lengthMmapRegion) { void* currentMmapRegion = mmapsList; struct headerMmapRegion *headerMmap = INIT_STRUCT(headerMmapRegion, currentMmapRegion); do { uint64_t oldLength = WORDS_TO_BYTES(headerMmap->length); void* endMmapRegion = currentMmapRegion + oldLength; if(endMmapRegion == newMmapRegion) { // Coalesce mmap regions. uint32_t newLength = headerMmap->length + BYTES_TO_WORDS(lengthMmapRegion); // update size mmap region. headerMmap->length = newLength; // Initialize footer mmap setMmapFooter(currentMmapRegion, WORDS_TO_BYTES(newLength)); // Calculate size new free region. void* beginningFreeRegion = ADDRESS_MINUS_OFFSET(endMmapRegion, blockHeader); uint64_t newFreeSpaceSize = lengthMmapRegion - sizeof(blockHeader); // size free region. struct blockHeader *footerPrevMmapRegion = INIT_STRUCT(blockHeader, beginningFreeRegion); uint32_t flag = GET_FLAG(footerPrevMmapRegion->attribute); // Coalesce with prev block if free. if (flag == MSB_TO_ONE) { void* previous = ADDRESS_MINUS_OFFSET(beginningFreeRegion, freeBlockFooter); struct freeBlockFooter *prevUsableBlockFooter = INIT_STRUCT(freeBlockFooter, previous); uint64_t sizePrevBlock = WORDS_TO_BYTES(prevUsableBlockFooter->size); // Footer has no flag beginningFreeRegion = beginningFreeRegion - sizePrevBlock - sizeof(blockHeader); newFreeSpaceSize += sizeof(blockHeader) + sizePrevBlock; numberFreeBlocks--; totalFreeSpace += newFreeSpaceSize; // Stats uint32_t newFreeSpaceSizeInWords = BYTES_TO_WORDS(newFreeSpaceSize); coalesceWithPrevBlock(beginningFreeRegion, newFreeSpaceSizeInWords); } else { initialiseFreeMmapRegion(beginningFreeRegion, newFreeSpaceSize); } return true; // coalescing. } else { // Check next mmap region currentMmapRegion = NEXT_MMAP_ADDRESS(headerMmap); headerMmap = currentMmapRegion; } } while (headerMmap != NULL && NEXT_MMAP_ADDRESS(headerMmap) != NULL); return false; // no coalescing. }
void coalesceWithPrevBlock(void* newAddr, uint32_t newSize) { struct blockHeader *newBlock = INIT_STRUCT(blockHeader, newAddr); newBlock->attribute = newSize; uint64_t sizeOffset = WORDS_TO_BYTES(newSize); setFooterBlockOnCoalescing(newAddr, sizeOffset, newSize); updateNextBlockOnCoalescing(newAddr, sizeOffset); }
void coalesceWithNeighbours(void* newAddr, uint32_t newSize, struct freeBlockLinks *successorBlockLinks) { struct blockHeader *newBlock = INIT_STRUCT(blockHeader, newAddr); newBlock->attribute = newSize; uint64_t sizeOffset = WORDS_TO_BYTES(newSize); setFooterBlockOnCoalescing(newAddr, sizeOffset, newSize); updateNextBlockOnCoalescing(newAddr, sizeOffset); // Remove successor block removeAllocatedBlock(successorBlockLinks); numberFreeBlocks--; }
void findAndSetLargestFreeBlock() { // traverse free list. largestFreeBlock = 0; // Reset largest free region. int numberTraversedNodes = 0; void* currentFreeBlock = freeList; do { struct blockHeader *currentFreeRegionHeader = INIT_STRUCT(blockHeader, currentFreeBlock); uint32_t sizeFreeRegion = GET_SIZE(currentFreeRegionHeader->attribute); // in words. uint64_t sizeFreeRegionInBytes = WORDS_TO_BYTES(sizeFreeRegion); if(sizeFreeRegionInBytes > largestFreeBlock) { largestFreeBlock = sizeFreeRegionInBytes; } void* freeBlock = ADDRESS_PLUS_OFFSET(currentFreeBlock, blockHeader); struct freeBlockLinks *currentBlockLinks = INIT_STRUCT(freeBlockLinks, freeBlock); numberTraversedNodes++; currentFreeBlock = NEXT_BLOCK(currentBlockLinks); } while (numberTraversedNodes < numberFreeBlocks); }
value stub_xl_send_sysrq(value domid, value sysrq) { CAMLparam2(domid, sysrq); int ret; INIT_STRUCT(); INIT_CTX(); ret = libxl_send_sysrq(&ctx, Int_val(domid), Int_val(sysrq)); if (ret != 0) failwith_xl("send_sysrq", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
value stub_xl_button_press(value domid, value button) { CAMLparam2(domid, button); int ret; INIT_STRUCT(); INIT_CTX(); ret = libxl_button_press(&ctx, Int_val(domid), Int_val(button) + POWER_BUTTON); if (ret != 0) failwith_xl("button_press", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
value stub_xl_pci_shutdown(value domid) { CAMLparam1(domid); int ret; INIT_STRUCT(); INIT_CTX(); ret = libxl_device_pci_shutdown(&ctx, Int_val(domid)); if (ret != 0) failwith_xl("pci_shutdown", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
int main(void) { //check_offloading(); S s1; ALLOC_STRUCT(s1); #if MAP_ALL printf("Map all\n"); INIT_STRUCT(s1); print(&s1); TEST_MAP( INIT_STRUCT(s1), _Pragma("omp target map(s1)"), { s1.a++; s1.c++; s1.e++; s1.x++; },
value stub_xl_send_debug_keys(value keys) { CAMLparam1(keys); int ret; char *c_keys; INIT_STRUCT(); c_keys = dup_String_val(&gc, keys); INIT_CTX(); ret = libxl_send_debug_keys(&ctx, c_keys); if (ret != 0) failwith_xl("send_debug_keys", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
value stub_xl_send_trigger(value domid, value trigger, value vcpuid) { CAMLparam3(domid, trigger, vcpuid); int ret; char *c_trigger; INIT_STRUCT(); c_trigger = dup_String_val(&gc, trigger); INIT_CTX(); ret = libxl_send_trigger(&ctx, Int_val(domid), c_trigger, Int_val(vcpuid)); if (ret != 0) failwith_xl("send_trigger", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
// // EV_ActivateAction // // Activate an action that has been looked up elsewhere. // bool EV_ActivateAction(ev_action_t *action, int *args, Mobj *thing) { if(!action) return false; INIT_STRUCT(ev_instance_t, instance); // setup instance instance.actor = thing; instance.args = args; instance.side = 0; instance.spac = SPAC_CROSS; instance.tag = args[0]; return !!EV_ActivateSpecial(action, &instance); }
value stub_xl_physinfo(value unit) { CAMLparam1(unit); CAMLlocal1(physinfo); libxl_physinfo c_physinfo; int ret; INIT_STRUCT(); INIT_CTX(); ret = libxl_get_physinfo(&ctx, &c_physinfo); if (ret != 0) failwith_xl("physinfo", &lg); FREE_CTX(); physinfo = Val_physinfo(&c_physinfo); CAMLreturn(physinfo); }
value stub_xl_sched_credit_domain_set(value domid, value scinfo) { CAMLparam2(domid, scinfo); libxl_sched_credit c_scinfo; int ret; INIT_STRUCT(); sched_credit_val(&gc, &c_scinfo, scinfo); INIT_CTX(); ret = libxl_sched_credit_domain_set(&ctx, Int_val(domid), &c_scinfo); if (ret != 0) failwith_xl("sched_credit_domain_set", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
value stub_xl_pci_remove(value info, value domid) { CAMLparam2(info, domid); libxl_device_pci c_info; int ret; INIT_STRUCT(); device_pci_val(&gc, &c_info, info); INIT_CTX(); ret = libxl_device_pci_remove(&ctx, Int_val(domid), &c_info, 0); if (ret != 0) failwith_xl("pci_remove", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
value stub_xl_sched_credit_domain_get(value domid) { CAMLparam1(domid); CAMLlocal1(scinfo); libxl_sched_credit c_scinfo; int ret; INIT_STRUCT(); INIT_CTX(); ret = libxl_sched_credit_domain_get(&ctx, Int_val(domid), &c_scinfo); if (ret != 0) failwith_xl("sched_credit_domain_get", &lg); FREE_CTX(); scinfo = Val_sched_credit(&c_scinfo); CAMLreturn(scinfo); }
value stub_xl_nic_add(value info, value domid) { CAMLparam2(info, domid); libxl_device_nic c_info; int ret; INIT_STRUCT(); device_nic_val(&gc, &c_info, info); c_info.domid = Int_val(domid); INIT_CTX(); ret = libxl_device_nic_add(&ctx, Int_val(domid), &c_info); if (ret != 0) failwith_xl("nic_add", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
void mmapRegion(uint64_t size) { uint64_t length; bool mmapRegionsCoalesced = false; // Make sure there's enough allocated memory. if (DEFAULT_NUMBER_MMAP_PAGES * sysconf(_SC_PAGE_SIZE) - (sizeof(headerMmapRegion) + sizeof(blockHeader)) < size) { uint64_t numberPages = (uint64_t) (size / sysconf(_SC_PAGE_SIZE)) + 1; length = numberPages * sysconf(_SC_PAGE_SIZE); } else { length = DEFAULT_NUMBER_MMAP_PAGES * sysconf(_SC_PAGE_SIZE); } newMmapRegion = MMAP(length); // TODO: check for errors if (newMmapRegion == MAP_FAILED) { fprintf(stderr, "memoryManagement.mmapRegion - Memory overflow\n"); exit(-1); } // Header Mmap region struct headerMmapRegion *headerMmap = INIT_STRUCT(headerMmapRegion, newMmapRegion); if (!mmapsList) { NEXT_MMAP_ADDRESS(headerMmap) = NULL; } else if (coalesceMmapRegions(mmapsList, newMmapRegion, length)) { mmapRegionsCoalesced = true; } else { NEXT_MMAP_ADDRESS(headerMmap) = mmapsList; // Add the new mmap at front. } if(!mmapRegionsCoalesced) { headerMmap->length = BYTES_TO_WORDS(length); mmapsList = newMmapRegion; // Update the pointer of mmapsList. setMmapFooter(newMmapRegion, length); // Set first free region. void* beginningFreeRegion = ADDRESS_PLUS_OFFSET(newMmapRegion, headerMmapRegion); // header free region and footer mmap to be excluded. uint64_t sizeFreeRegion = length - sizeof(headerMmapRegion) - (2 * sizeof(blockHeader)); initialiseFreeMmapRegion(beginningFreeRegion, sizeFreeRegion); } numberFreeBlocks++; // Add one free block to the counter. }
// // EV_ActivateSpecialNum // // Activate a special without a source linedef. Only some specials support // this; ones which don't will return false in their preamble. // bool EV_ActivateSpecialNum(int special, int *args, Mobj *thing) { ev_action_t *action; INIT_STRUCT(ev_instance_t, instance); // setup instance instance.actor = thing; instance.args = args; instance.special = special; instance.side = 0; instance.spac = SPAC_CROSS; instance.tag = args[0]; // get action if(!(action = EV_ActionForInstance(instance))) return false; return !!EV_ActivateSpecial(action, &instance); }
// // EV_ActivateACSSpecial // // Activate a special for ACS. // int EV_ActivateACSSpecial(line_t *line, int special, int *args, int side, Mobj *thing) { ev_action_t *action; INIT_STRUCT(ev_instance_t, instance); // setup instance instance.actor = thing; instance.args = args; instance.line = line; instance.special = special; instance.side = side; instance.spac = SPAC_CROSS; instance.tag = args[0]; // get action (always from within the Hexen namespace) if(!(action = EV_HexenActionForSpecial(special))) return false; return EV_ActivateSpecial(action, &instance); }
value stub_xl_console_add(value info, value state, value domid) { CAMLparam3(info, state, domid); libxl_device_console c_info; libxl_domain_build_state c_state; int ret; INIT_STRUCT(); device_console_val(&gc, &c_info, info); domain_build_state_val(&gc, &c_state, state); c_info.domid = Int_val(domid); c_info.build_state = &c_state; INIT_CTX(); ret = libxl_device_console_add(&ctx, Int_val(domid), &c_info); if (ret != 0) failwith_xl("console_add", &lg); FREE_CTX(); CAMLreturn(Val_unit); }
void freeMemory(void *ptr) { /* Read flag for coalescing with previous block Read size to get to the next block and check if it's free (coalescing) */ void *startBlock = ADDRESS_MINUS_OFFSET(ptr, blockHeader); struct blockHeader *header = INIT_STRUCT(blockHeader, startBlock); uint32_t size = GET_SIZE(header->attribute); // in words if(!freeList) { initialiseFreeBlock(startBlock, size, startBlock, startBlock, false, false); freeList = startBlock; numberFreeBlocks++; totalFreeSpace += WORDS_TO_BYTES(size); // Stats } else { coalescingAndFree(startBlock); } currentAllocatedMemory -= WORDS_TO_BYTES(size); }