int rawdv_close(dv_t *dv) { close(dv->fd); mmap_free(dv->mmap_region); rawdv_free( dv); return 1; }
void * mmap_realloc (void **var, size_t nbytes) { MEMORY_BASIC_INFORMATION memInfo, m2; void *old_ptr; if (*var == NULL) return mmap_alloc (var, nbytes); /* This case happens in init_buffer(). */ if (nbytes == 0) { mmap_free (var); return mmap_alloc (var, nbytes); } memset (&memInfo, 0, sizeof (memInfo)); if (VirtualQuery (*var, &memInfo, sizeof (memInfo)) == 0) DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ())); /* We need to enlarge the block. */ if (memInfo.RegionSize < nbytes) { memset (&m2, 0, sizeof (m2)); if (VirtualQuery ((char *)*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0) DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ())); /* If there is enough room in the current reserved area, then commit more pages as needed. */ if (m2.State == MEM_RESERVE && m2.AllocationBase == memInfo.AllocationBase && nbytes <= memInfo.RegionSize + m2.RegionSize) { void *p; p = VirtualAlloc (*var, nbytes, MEM_COMMIT, PAGE_READWRITE); if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */) { DebPrint (("realloc enlarge: VirtualAlloc (%p + %I64x, %I64x) error %ld\n", *var, (uint64_t)memInfo.RegionSize, (uint64_t)(nbytes - memInfo.RegionSize), GetLastError ())); DebPrint (("next region: %p %p %I64x %x\n", m2.BaseAddress, m2.AllocationBase, (uint64_t)m2.RegionSize, m2.AllocationProtect)); } else return *var; } /* Else we must actually enlarge the block by allocating a new one and copying previous contents from the old to the new one. */ old_ptr = *var; if (mmap_alloc (var, nbytes)) { CopyMemory (*var, old_ptr, memInfo.RegionSize); mmap_free (&old_ptr); return *var; } else { /* We failed to reallocate the buffer. */ *var = old_ptr; return NULL; } } /* If we are shrinking by more than one page... */ if (memInfo.RegionSize > nbytes + getpagesize()) { /* If we are shrinking a lot... */ if ((memInfo.RegionSize / 2) > nbytes) { /* Let's give some memory back to the system and release some pages. */ old_ptr = *var; if (mmap_alloc (var, nbytes)) { CopyMemory (*var, old_ptr, nbytes); mmap_free (&old_ptr); return *var; } else { /* In case we fail to shrink, try to go on with the old block. But that means there is a lot of memory pressure. We could also decommit pages. */ *var = old_ptr; return *var; } } /* We still can decommit pages. */ if (VirtualFree ((char *)*var + nbytes + get_page_size(), memInfo.RegionSize - nbytes - get_page_size(), MEM_DECOMMIT) == 0) DebPrint (("mmap_realloc: VirtualFree error %ld\n", GetLastError ())); return *var; } /* Not enlarging, not shrinking by more than one page. */ return *var; }
~page() { mmap_free( _data, PageSize ); }