⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sharedpool.cpp

📁 DVD工具dvdsynth的源码
💻 CPP
字号:
/***********************************************************************
 Copyright 2002 Ben Rudiak-Gould.

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
 or visit <http://www.gnu.org/copyleft/gpl.html>.
***********************************************************************/


#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>

#include "SharedPool.h"
#include "miniport.h"

/*******************************************************************\
\*******************************************************************/


inline void* PageReserve(unsigned npages) {
   return VirtualAlloc(NULL, npages*4096, MEM_RESERVE, PAGE_READWRITE);
}

inline bool PageCommit(void* p, unsigned npages) {
   return !!VirtualAlloc(p, npages*4096, MEM_COMMIT, PAGE_READWRITE);
}

inline unsigned PageFree(void* p) {
   return VirtualFree(p, 0, MEM_RELEASE);
}


/*******************************************************************\
\*******************************************************************/


class SharedPool {
   char* latest_block_next_free_byte;
   char* latest_block_end;
   unsigned latest_block_index;
   int locked;
   char* blocks[18];

public:
   static void* Create(int _locked);
   void* Allocate(unsigned len);
   void Clear();
   void Delete();
};

inline void* SharedPool::Create(int _locked) {
   char* block = (char*)PageReserve(1);
   if (!block) {
      return 0;
   }
   if (!PageCommit(block, 1)) {
      PageFree(block);
      return 0;
   }
   SharedPool* self = (SharedPool*)block;
   self->latest_block_next_free_byte = block + sizeof(SharedPool);
   self->latest_block_end = block + 4096;
   self->locked = _locked;
   self->blocks[0] = block;
   return self;
}

inline void* SharedPool::Allocate(unsigned len) {
   len = (len+3) & -4;

   char* alloc_end = latest_block_next_free_byte + len;
   if (alloc_end > latest_block_end) {
      // Current block isn't big enough; allocate a new one. The size of
      // block N is at least 4K * 2^N, to ensure that we'll run out of
      // virtual address space before we run out of array slots.
      unsigned pages_to_alloc = max((len + 4095U) >> 12, 2U << latest_block_index);
      char* new_block = (char*)PageReserve(pages_to_alloc);
      if (new_block == 0) {
         return 0;
      }
      latest_block_next_free_byte = new_block;
      latest_block_end = new_block + pages_to_alloc*4096;
      ++latest_block_index;
      blocks[latest_block_index] = new_block;
      alloc_end = new_block + len;
   }
   char* first_uncommitted_byte = (char*)(((unsigned)latest_block_next_free_byte + 4095) & -4096);
   if (alloc_end > first_uncommitted_byte) {
      unsigned pages_to_commit = (alloc_end - first_uncommitted_byte + 4095) >> 12;
      if (!PageCommit(first_uncommitted_byte, pages_to_commit)) {
         return 0;
      }
   }
   void* rtn = latest_block_next_free_byte;
   latest_block_next_free_byte = alloc_end;
   return rtn;
}


inline void SharedPool::Clear() {
   for (unsigned i=1; i<=latest_block_index; ++i) {
      PageFree(blocks[i]);
   }
   latest_block_next_free_byte = blocks[0] + sizeof(SharedPool);
   latest_block_end = blocks[0] + 4096;
   latest_block_index = 0;
}

inline void SharedPool::Delete() {
   for (unsigned i=1; i<=latest_block_index; ++i) {
      PageFree(blocks[i]);
   }
   PageFree(blocks[0]);
}


void* SharedPool_Create(int locked) {
   return SharedPool::Create(locked);
}
void* SharedPool_Alloc(void* self, unsigned len) {
   return ((SharedPool*)self)->Allocate(len);
}
void SharedPool_Clear(void* self) {
   ((SharedPool*)self)->Clear();
}
void SharedPool_Delete(void* self) {
   ((SharedPool*)self)->Delete();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -