gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

390 line
16KB

  1. /**********************************************************************
  2. * $Id: cpl_virtualmem.h aa47027b5633ab93caafae35f82f5e53c72ed05c 2016-11-24 07:54:20Z Kurt Schwehr $
  3. *
  4. * Name: cpl_virtualmem.h
  5. * Project: CPL - Common Portability Library
  6. * Purpose: Virtual memory
  7. * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
  8. *
  9. **********************************************************************
  10. * Copyright (c) 2014, Even Rouault <even dot rouault at mines-paris dot org>
  11. *
  12. * Permission is hereby granted, free of charge, to any person obtaining a
  13. * copy of this software and associated documentation files (the "Software"),
  14. * to deal in the Software without restriction, including without limitation
  15. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  16. * and/or sell copies of the Software, and to permit persons to whom the
  17. * Software is furnished to do so, subject to the following conditions:
  18. *
  19. * The above copyright notice and this permission notice shall be included
  20. * in all copies or substantial portions of the Software.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  25. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  27. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  28. * DEALINGS IN THE SOFTWARE.
  29. ****************************************************************************/
  30. #ifndef CPL_VIRTUAL_MEM_INCLUDED
  31. #define CPL_VIRTUAL_MEM_INCLUDED
  32. #include <stddef.h>
  33. #include "cpl_port.h"
  34. #include "cpl_vsi.h"
  35. CPL_C_START
  36. /**
  37. * \file cpl_virtualmem.h
  38. *
  39. * Virtual memory management.
  40. *
  41. * This file provides mechanism to define virtual memory mappings, whose content
  42. * is allocated transparently and filled on-the-fly. Those virtual memory mappings
  43. * can be much larger than the available RAM, but only parts of the virtual
  44. * memory mapping, in the limit of the allowed the cache size, will actually be
  45. * physically allocated.
  46. *
  47. * This exploits low-level mechanisms of the operating system (virtual memory
  48. * allocation, page protection and handler of virtual memory exceptions).
  49. *
  50. * It is also possible to create a virtual memory mapping from a file or part
  51. * of a file.
  52. *
  53. * The current implementation is Linux only.
  54. */
  55. /** Opaque type that represents a virtual memory mapping. */
  56. typedef struct CPLVirtualMem CPLVirtualMem;
  57. /** Callback triggered when a still unmapped page of virtual memory is accessed.
  58. * The callback has the responsibility of filling the page with relevant values
  59. *
  60. * @param ctxt virtual memory handle.
  61. * @param nOffset offset of the page in the memory mapping.
  62. * @param pPageToFill address of the page to fill. Note that the address might
  63. * be a temporary location, and not at CPLVirtualMemGetAddr() + nOffset.
  64. * @param nToFill number of bytes of the page.
  65. * @param pUserData user data that was passed to CPLVirtualMemNew().
  66. */
  67. typedef void (*CPLVirtualMemCachePageCbk)(CPLVirtualMem* ctxt,
  68. size_t nOffset,
  69. void* pPageToFill,
  70. size_t nToFill,
  71. void* pUserData);
  72. /** Callback triggered when a dirty mapped page is going to be freed.
  73. * (saturation of cache, or termination of the virtual memory mapping).
  74. *
  75. * @param ctxt virtual memory handle.
  76. * @param nOffset offset of the page in the memory mapping.
  77. * @param pPageToBeEvicted address of the page that will be flushed. Note that the address might
  78. * be a temporary location, and not at CPLVirtualMemGetAddr() + nOffset.
  79. * @param nToBeEvicted number of bytes of the page.
  80. * @param pUserData user data that was passed to CPLVirtualMemNew().
  81. */
  82. typedef void (*CPLVirtualMemUnCachePageCbk)(CPLVirtualMem* ctxt,
  83. size_t nOffset,
  84. const void* pPageToBeEvicted,
  85. size_t nToBeEvicted,
  86. void* pUserData);
  87. /** Callback triggered when a virtual memory mapping is destroyed.
  88. * @param pUserData user data that was passed to CPLVirtualMemNew().
  89. */
  90. typedef void (*CPLVirtualMemFreeUserData)(void* pUserData);
  91. /** Access mode of a virtual memory mapping. */
  92. typedef enum
  93. {
  94. /*! The mapping is meant at being read-only, but writes will not be prevented.
  95. Note that any content written will be lost. */
  96. VIRTUALMEM_READONLY,
  97. /*! The mapping is meant at being read-only, and this will be enforced
  98. through the operating system page protection mechanism. */
  99. VIRTUALMEM_READONLY_ENFORCED,
  100. /*! The mapping is meant at being read-write, and modified pages can be saved
  101. thanks to the pfnUnCachePage callback */
  102. VIRTUALMEM_READWRITE
  103. } CPLVirtualMemAccessMode;
  104. /** Return the size of a page of virtual memory.
  105. *
  106. * @return the page size.
  107. *
  108. * @since GDAL 1.11
  109. */
  110. size_t CPL_DLL CPLGetPageSize(void);
  111. /** Create a new virtual memory mapping.
  112. *
  113. * This will reserve an area of virtual memory of size nSize, whose size
  114. * might be potentially much larger than the physical memory available. Initially,
  115. * no physical memory will be allocated. As soon as memory pages will be accessed,
  116. * they will be allocated transparently and filled with the pfnCachePage callback.
  117. * When the allowed cache size is reached, the least recently used pages will
  118. * be unallocated.
  119. *
  120. * On Linux AMD64 platforms, the maximum value for nSize is 128 TB.
  121. * On Linux x86 platforms, the maximum value for nSize is 2 GB.
  122. *
  123. * Only supported on Linux for now.
  124. *
  125. * Note that on Linux, this function will install a SIGSEGV handler. The
  126. * original handler will be restored by CPLVirtualMemManagerTerminate().
  127. *
  128. * @param nSize size in bytes of the virtual memory mapping.
  129. * @param nCacheSize size in bytes of the maximum memory that will be really
  130. * allocated (must ideally fit into RAM).
  131. * @param nPageSizeHint hint for the page size. Must be a multiple of the
  132. * system page size, returned by CPLGetPageSize().
  133. * Minimum value is generally 4096. Might be set to 0 to
  134. * let the function determine a default page size.
  135. * @param bSingleThreadUsage set to TRUE if there will be no concurrent threads
  136. * that will access the virtual memory mapping. This can
  137. * optimize performance a bit.
  138. * @param eAccessMode permission to use for the virtual memory mapping.
  139. * @param pfnCachePage callback triggered when a still unmapped page of virtual
  140. * memory is accessed. The callback has the responsibility
  141. * of filling the page with relevant values.
  142. * @param pfnUnCachePage callback triggered when a dirty mapped page is going to
  143. * be freed (saturation of cache, or termination of the
  144. * virtual memory mapping). Might be NULL.
  145. * @param pfnFreeUserData callback that can be used to free pCbkUserData. Might be
  146. * NULL
  147. * @param pCbkUserData user data passed to pfnCachePage and pfnUnCachePage.
  148. *
  149. * @return a virtual memory object that must be freed by CPLVirtualMemFree(),
  150. * or NULL in case of failure.
  151. *
  152. * @since GDAL 1.11
  153. */
  154. CPLVirtualMem CPL_DLL *CPLVirtualMemNew(size_t nSize,
  155. size_t nCacheSize,
  156. size_t nPageSizeHint,
  157. int bSingleThreadUsage,
  158. CPLVirtualMemAccessMode eAccessMode,
  159. CPLVirtualMemCachePageCbk pfnCachePage,
  160. CPLVirtualMemUnCachePageCbk pfnUnCachePage,
  161. CPLVirtualMemFreeUserData pfnFreeUserData,
  162. void *pCbkUserData);
  163. /** Return if virtual memory mapping of a file is available.
  164. *
  165. * @return TRUE if virtual memory mapping of a file is available.
  166. * @since GDAL 1.11
  167. */
  168. int CPL_DLL CPLIsVirtualMemFileMapAvailable(void);
  169. /** Create a new virtual memory mapping from a file.
  170. *
  171. * The file must be a "real" file recognized by the operating system, and not
  172. * a VSI extended virtual file.
  173. *
  174. * In VIRTUALMEM_READWRITE mode, updates to the memory mapping will be written
  175. * in the file.
  176. *
  177. * On Linux AMD64 platforms, the maximum value for nLength is 128 TB.
  178. * On Linux x86 platforms, the maximum value for nLength is 2 GB.
  179. *
  180. * Supported on Linux only in GDAL <= 2.0, and all POSIX systems supporting
  181. * mmap() in GDAL >= 2.1
  182. *
  183. * @param fp Virtual file handle.
  184. * @param nOffset Offset in the file to start the mapping from.
  185. * @param nLength Length of the portion of the file to map into memory.
  186. * @param eAccessMode Permission to use for the virtual memory mapping. This must
  187. * be consistent with how the file has been opened.
  188. * @param pfnFreeUserData callback that is called when the object is destroyed.
  189. * @param pCbkUserData user data passed to pfnFreeUserData.
  190. * @return a virtual memory object that must be freed by CPLVirtualMemFree(),
  191. * or NULL in case of failure.
  192. *
  193. * @since GDAL 1.11
  194. */
  195. CPLVirtualMem CPL_DLL *CPLVirtualMemFileMapNew( VSILFILE* fp,
  196. vsi_l_offset nOffset,
  197. vsi_l_offset nLength,
  198. CPLVirtualMemAccessMode eAccessMode,
  199. CPLVirtualMemFreeUserData pfnFreeUserData,
  200. void *pCbkUserData );
  201. /** Create a new virtual memory mapping derived from an other virtual memory
  202. * mapping.
  203. *
  204. * This may be useful in case of creating mapping for pixel interleaved data.
  205. *
  206. * The new mapping takes a reference on the base mapping.
  207. *
  208. * @param pVMemBase Base virtual memory mapping
  209. * @param nOffset Offset in the base virtual memory mapping from which to start
  210. * the new mapping.
  211. * @param nSize Size of the base virtual memory mapping to expose in the
  212. * the new mapping.
  213. * @param pfnFreeUserData callback that is called when the object is destroyed.
  214. * @param pCbkUserData user data passed to pfnFreeUserData.
  215. * @return a virtual memory object that must be freed by CPLVirtualMemFree(),
  216. * or NULL in case of failure.
  217. *
  218. * @since GDAL 1.11
  219. */
  220. CPLVirtualMem CPL_DLL *CPLVirtualMemDerivedNew(CPLVirtualMem* pVMemBase,
  221. vsi_l_offset nOffset,
  222. vsi_l_offset nSize,
  223. CPLVirtualMemFreeUserData pfnFreeUserData,
  224. void *pCbkUserData);
  225. /** Free a virtual memory mapping.
  226. *
  227. * The pointer returned by CPLVirtualMemGetAddr() will no longer be valid.
  228. * If the virtual memory mapping was created with read/write permissions and that
  229. * they are dirty (i.e. modified) pages, they will be flushed through the
  230. * pfnUnCachePage callback before being freed.
  231. *
  232. * @param ctxt context returned by CPLVirtualMemNew().
  233. *
  234. * @since GDAL 1.11
  235. */
  236. void CPL_DLL CPLVirtualMemFree(CPLVirtualMem* ctxt);
  237. /** Return the pointer to the start of a virtual memory mapping.
  238. *
  239. * The bytes in the range [p:p+CPLVirtualMemGetSize()-1] where p is the pointer
  240. * returned by this function will be valid, until CPLVirtualMemFree() is called.
  241. *
  242. * Note that if a range of bytes used as an argument of a system call
  243. * (such as read() or write()) contains pages that have not been "realized", the
  244. * system call will fail with EFAULT. CPLVirtualMemPin() can be used to work
  245. * around this issue.
  246. *
  247. * @param ctxt context returned by CPLVirtualMemNew().
  248. * @return the pointer to the start of a virtual memory mapping.
  249. *
  250. * @since GDAL 1.11
  251. */
  252. void CPL_DLL *CPLVirtualMemGetAddr(CPLVirtualMem* ctxt);
  253. /** Return the size of the virtual memory mapping.
  254. *
  255. * @param ctxt context returned by CPLVirtualMemNew().
  256. * @return the size of the virtual memory mapping.
  257. *
  258. * @since GDAL 1.11
  259. */
  260. size_t CPL_DLL CPLVirtualMemGetSize(CPLVirtualMem* ctxt);
  261. /** Return if the virtual memory mapping is a direct file mapping.
  262. *
  263. * @param ctxt context returned by CPLVirtualMemNew().
  264. * @return TRUE if the virtual memory mapping is a direct file mapping.
  265. *
  266. * @since GDAL 1.11
  267. */
  268. int CPL_DLL CPLVirtualMemIsFileMapping(CPLVirtualMem* ctxt);
  269. /** Return the access mode of the virtual memory mapping.
  270. *
  271. * @param ctxt context returned by CPLVirtualMemNew().
  272. * @return the access mode of the virtual memory mapping.
  273. *
  274. * @since GDAL 1.11
  275. */
  276. CPLVirtualMemAccessMode CPL_DLL CPLVirtualMemGetAccessMode(CPLVirtualMem* ctxt);
  277. /** Return the page size associated to a virtual memory mapping.
  278. *
  279. * The value returned will be at least CPLGetPageSize(), but potentially
  280. * larger.
  281. *
  282. * @param ctxt context returned by CPLVirtualMemNew().
  283. * @return the page size
  284. *
  285. * @since GDAL 1.11
  286. */
  287. size_t CPL_DLL CPLVirtualMemGetPageSize(CPLVirtualMem* ctxt);
  288. /** Return TRUE if this memory mapping can be accessed safely from concurrent
  289. * threads.
  290. *
  291. * The situation that can cause problems is when several threads try to access
  292. * a page of the mapping that is not yet mapped.
  293. *
  294. * The return value of this function depends on whether bSingleThreadUsage has
  295. * been set of not in CPLVirtualMemNew() and/or the implementation.
  296. *
  297. * On Linux, this will always return TRUE if bSingleThreadUsage = FALSE.
  298. *
  299. * @param ctxt context returned by CPLVirtualMemNew().
  300. * @return TRUE if this memory mapping can be accessed safely from concurrent
  301. * threads.
  302. *
  303. * @since GDAL 1.11
  304. */
  305. int CPL_DLL CPLVirtualMemIsAccessThreadSafe(CPLVirtualMem* ctxt);
  306. /** Declare that a thread will access a virtual memory mapping.
  307. *
  308. * This function must be called by a thread that wants to access the
  309. * content of a virtual memory mapping, except if the virtual memory mapping has
  310. * been created with bSingleThreadUsage = TRUE.
  311. *
  312. * This function must be paired with CPLVirtualMemUnDeclareThread().
  313. *
  314. * @param ctxt context returned by CPLVirtualMemNew().
  315. *
  316. * @since GDAL 1.11
  317. */
  318. void CPL_DLL CPLVirtualMemDeclareThread(CPLVirtualMem* ctxt);
  319. /** Declare that a thread will stop accessing a virtual memory mapping.
  320. *
  321. * This function must be called by a thread that will no longer access the
  322. * content of a virtual memory mapping, except if the virtual memory mapping has
  323. * been created with bSingleThreadUsage = TRUE.
  324. *
  325. * This function must be paired with CPLVirtualMemDeclareThread().
  326. *
  327. * @param ctxt context returned by CPLVirtualMemNew().
  328. *
  329. * @since GDAL 1.11
  330. */
  331. void CPL_DLL CPLVirtualMemUnDeclareThread(CPLVirtualMem* ctxt);
  332. /** Make sure that a region of virtual memory will be realized.
  333. *
  334. * Calling this function is not required, but might be useful when debugging
  335. * a process with tools like gdb or valgrind that do not naturally like
  336. * segmentation fault signals.
  337. *
  338. * It is also needed when wanting to provide part of virtual memory mapping
  339. * to a system call such as read() or write(). If read() or write() is called
  340. * on a memory region not yet realized, the call will fail with EFAULT.
  341. *
  342. * @param ctxt context returned by CPLVirtualMemNew().
  343. * @param pAddr the memory region to pin.
  344. * @param nSize the size of the memory region.
  345. * @param bWriteOp set to TRUE if the memory are will be accessed in write mode.
  346. *
  347. * @since GDAL 1.11
  348. */
  349. void CPL_DLL CPLVirtualMemPin(CPLVirtualMem* ctxt,
  350. void* pAddr, size_t nSize, int bWriteOp);
  351. /** Cleanup any resource and handlers related to virtual memory.
  352. *
  353. * This function must be called after the last CPLVirtualMem object has
  354. * been freed.
  355. *
  356. * @since GDAL 2.0
  357. */
  358. void CPL_DLL CPLVirtualMemManagerTerminate(void);
  359. CPL_C_END
  360. #endif /* CPL_VIRTUAL_MEM_INCLUDED */
上海开阖软件有限公司 沪ICP备12045867号-1