예제 #1
0
int	rawdv_close(dv_t *dv)
{
	close(dv->fd);
	mmap_free(dv->mmap_region);
	rawdv_free( dv);
	return 1;
}
예제 #2
0
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;
}
예제 #3
0
 ~page()
 {
   mmap_free( _data, PageSize );
 }