home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / system / source / memory.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-10-13  |  7.6 KB  |  354 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #include "stdafx.h"
  27. #include <malloc.h>
  28. #include <windows.h>
  29. #include <vd2/system/atomic.h>
  30. #include <vd2/system/memory.h>
  31. #include <vd2/system/cpuaccel.h>
  32.  
  33. void *VDAlignedMalloc(size_t n, unsigned alignment) {
  34.     return _aligned_malloc(n, alignment);
  35. }
  36.  
  37. void VDAlignedFree(void *p) {
  38.     _aligned_free(p);
  39. }
  40.  
  41. void VDSwapMemory(void *p0, void *p1, unsigned bytes) {
  42.     long *dst0 = (long *)p0;
  43.     long *dst1 = (long *)p1;
  44.  
  45.     while(bytes >= 4) {
  46.         long a = *dst0;
  47.         long b = *dst1;
  48.  
  49.         *dst0++ = b;
  50.         *dst1++ = a;
  51.  
  52.         bytes -= 4;
  53.     }
  54.  
  55.     char *dstb0 = (char *)dst0;
  56.     char *dstb1 = (char *)dst1;
  57.  
  58.     while(bytes--) {
  59.         char a = *dstb0;
  60.         char b = *dstb1;
  61.  
  62.         *dstb0++ = b;
  63.         *dstb1++ = a;
  64.     }
  65. }
  66.  
  67. void VDInvertMemory(void *p, unsigned bytes) {
  68.     char *dst = (char *)p;
  69.  
  70.     if (!bytes)
  71.         return;
  72.  
  73.     while((int)dst & 3) {
  74.         *dst = ~*dst;
  75.         ++dst;
  76.  
  77.         if (!--bytes)
  78.             return;
  79.     }
  80.  
  81.     unsigned lcount = bytes >> 2;
  82.  
  83.     if (lcount)
  84.         do {
  85.             *(long *)dst = ~*(long *)dst;
  86.             dst += 4;
  87.         } while(--lcount);
  88.  
  89.     bytes &= 3;
  90.  
  91.     while(bytes--) {
  92.         *dst = ~*dst;
  93.         ++dst;
  94.     }
  95. }
  96.  
  97. namespace {
  98.     uintptr VDGetSystemPageSizeW32() {
  99.         SYSTEM_INFO sysInfo;
  100.         GetSystemInfo(&sysInfo);
  101.  
  102.         return sysInfo.dwPageSize;
  103.     }
  104.  
  105.     uintptr VDGetSystemPageSize() {
  106.         static uintptr pageSize = VDGetSystemPageSizeW32();
  107.  
  108.         return pageSize;
  109.     }
  110. }
  111.  
  112. bool VDIsValidReadRegion(const void *p0, size_t bytes) {
  113.     if (!bytes)
  114.         return true;
  115.  
  116.     if (!p0)
  117.         return false;
  118.  
  119.     uintptr pageSize = VDGetSystemPageSize();
  120.     uintptr p = (uintptr)p0;
  121.     uintptr pLimit = p + (bytes-1);
  122.  
  123.     __try {
  124.         for(;;) {
  125.             *(volatile char *)p;
  126.  
  127.             if (pLimit - p < pageSize)
  128.                 break;
  129.  
  130.             p += pageSize;
  131.         }
  132.     } __except(1) {
  133.         return false;
  134.     }
  135.  
  136.     return true;
  137. }
  138.  
  139. bool VDIsValidWriteRegion(const void *p0, size_t bytes) {
  140.     if (!bytes)
  141.         return true;
  142.  
  143.     if (!p0)
  144.         return false;
  145.  
  146.     // Note: Unlike IsValidWritePtr(), this is threadsafe.
  147.  
  148.     uintptr pageSize = VDGetSystemPageSize();
  149.     uintptr p = (uintptr)p0;
  150.     uintptr pLimit = p + (bytes-1);
  151.     p &= ~(uintptr)3;
  152.  
  153.     __try {
  154.         for(;;) {
  155.             VDAtomicInt::staticCompareExchange((volatile int *)p, 0xa5, 0xa5);
  156.  
  157.             if (pLimit - p < pageSize)
  158.                 break;
  159.  
  160.             p += pageSize;
  161.         }
  162.     } __except(1) {
  163.         return false;
  164.     }
  165.  
  166.     return true;
  167. }
  168.  
  169. bool VDCompareRect(void *dst, ptrdiff_t dstpitch, const void *src, ptrdiff_t srcpitch, size_t w, size_t h) {
  170.     if (!w || !h)
  171.         return false;
  172.  
  173.     do {
  174.         if (memcmp(dst, src, w))
  175.             return true;
  176.  
  177.         dst = (char *)dst + dstpitch;
  178.         src = (const char *)src + srcpitch;
  179.     } while(--h);
  180.  
  181.     return false;
  182. }
  183.  
  184. void VDMemset8(void *dst, uint8 value, size_t count) {
  185.     if (count) {
  186.         uint8 *dst2 = (uint8 *)dst;
  187.  
  188.         do {
  189.             *dst2++ = value;
  190.         } while(--count);
  191.     }
  192. }
  193.  
  194. void VDMemset16(void *dst, uint16 value, size_t count) {
  195.     if (count) {
  196.         uint16 *dst2 = (uint16 *)dst;
  197.  
  198.         do {
  199.             *dst2++ = value;
  200.         } while(--count);
  201.     }
  202. }
  203.  
  204. void VDMemset32(void *dst, uint32 value, size_t count) {
  205.     if (count) {
  206.         uint32 *dst2 = (uint32 *)dst;
  207.  
  208.         do {
  209.             *dst2++ = value;
  210.         } while(--count);
  211.     }
  212. }
  213.  
  214. void VDMemset64(void *dst, uint64 value, size_t count) {
  215.     if (count) {
  216.         uint64 *dst2 = (uint64 *)dst;
  217.  
  218.         do {
  219.             *dst2++ = value;
  220.         } while(--count);
  221.     }
  222. }
  223.  
  224. void VDMemset128(void *dst, const void *src0, size_t count) {
  225.     if (count) {
  226.         const uint32 *src = (const uint32 *)src0;
  227.         uint32 a0 = src[0];
  228.         uint32 a1 = src[1];
  229.         uint32 a2 = src[2];
  230.         uint32 a3 = src[3];
  231.  
  232.         uint32 *dst2 = (uint32 *)dst;
  233.  
  234.         do {
  235.             dst2[0] = a0;
  236.             dst2[1] = a1;
  237.             dst2[2] = a2;
  238.             dst2[3] = a3;
  239.             dst2 += 4;
  240.         } while(--count);
  241.     }
  242. }
  243.  
  244. void VDMemsetPointer(void *dst, const void *value, size_t count) {
  245. #if defined(_M_IX86)
  246.     VDMemset32(dst, (uint32)(size_t)value, count);
  247. #elif defined(_M_AMD64)
  248.     VDMemset64(dst, (uint64)(size_t)value, count);
  249. #else
  250.     #error Unknown pointer size
  251. #endif
  252. }
  253.  
  254. void VDMemset8Rect(void *dst, ptrdiff_t pitch, uint8 value, size_t w, size_t h) {
  255.     if (w>0 && h>0) {
  256.         do {
  257.             memset(dst, value, w);
  258.             dst = (char *)dst + pitch;
  259.         } while(--h);
  260.     }
  261. }
  262.  
  263. void VDMemset16Rect(void *dst, ptrdiff_t pitch, uint16 value, size_t w, size_t h) {
  264.     if (w>0 && h>0) {
  265.         do {
  266.             VDMemset16(dst, value, w);
  267.             dst = (char *)dst + pitch;
  268.         } while(--h);
  269.     }
  270. }
  271.  
  272. void VDMemset32Rect(void *dst, ptrdiff_t pitch, uint32 value, size_t w, size_t h) {
  273.     if (w>0 && h>0) {
  274.         do {
  275.             VDMemset32(dst, value, w);
  276.             dst = (char *)dst + pitch;
  277.         } while(--h);
  278.     }
  279. }
  280.  
  281. #if defined(_WIN32) && defined(_M_IX86)
  282.     extern "C" void __cdecl VDFastMemcpyPartialScalarAligned8(void *dst, const void *src, size_t bytes);
  283.     extern "C" void __cdecl VDFastMemcpyPartialMMX(void *dst, const void *src, size_t bytes);
  284.     extern "C" void __cdecl VDFastMemcpyPartialMMX2(void *dst, const void *src, size_t bytes);
  285.  
  286.     void VDFastMemcpyPartialScalar(void *dst, const void *src, size_t bytes) {
  287.         if (!(((int)dst | (int)src | bytes) & 7))
  288.             VDFastMemcpyPartialScalarAligned8(dst, src, bytes);
  289.         else
  290.             memcpy(dst, src, bytes);
  291.     }
  292.  
  293.     void VDFastMemcpyFinishScalar() {
  294.     }
  295.  
  296.     void __cdecl VDFastMemcpyFinishMMX() {
  297.         __asm emms
  298.     }
  299.  
  300.     void __cdecl VDFastMemcpyFinishMMX2() {
  301.         __asm emms
  302.         __asm sfence
  303.     }
  304.  
  305.     void (__cdecl *VDFastMemcpyPartial)(void *dst, const void *src, size_t bytes) = VDFastMemcpyPartialScalar;
  306.     void (__cdecl *VDFastMemcpyFinish)() = VDFastMemcpyFinishScalar;
  307.  
  308.     void VDFastMemcpyAutodetect() {
  309.         long exts = CPUGetEnabledExtensions();
  310.  
  311.         if (exts & CPUF_SUPPORTS_INTEGER_SSE) {
  312.             VDFastMemcpyPartial = VDFastMemcpyPartialMMX2;
  313.             VDFastMemcpyFinish    = VDFastMemcpyFinishMMX2;
  314.         } else if (exts & CPUF_SUPPORTS_MMX) {
  315.             VDFastMemcpyPartial = VDFastMemcpyPartialMMX;
  316.             VDFastMemcpyFinish    = VDFastMemcpyFinishMMX;
  317.         } else {
  318.             VDFastMemcpyPartial = VDFastMemcpyPartialScalar;
  319.             VDFastMemcpyFinish    = VDFastMemcpyFinishScalar;
  320.         }
  321.     }
  322.  
  323. #else
  324.     void VDFastMemcpyPartial(void *dst, const void *src, size_t bytes) {
  325.         memcpy(dst, src, bytes);
  326.     }
  327.  
  328.     void VDFastMemcpyFinish() {
  329.     }
  330.  
  331.     void VDFastMemcpyAutodetect() {
  332.     }
  333. #endif
  334.  
  335. void VDMemcpyRect(void *dst, ptrdiff_t dststride, const void *src, ptrdiff_t srcstride, size_t w, size_t h) {
  336.     if (w <= 0 || h <= 0)
  337.         return;
  338.  
  339.     if (w == srcstride && w == dststride)
  340.         VDFastMemcpyPartial(dst, src, w*h);
  341.     else {
  342.         char *dst2 = (char *)dst;
  343.         const char *src2 = (const char *)src;
  344.  
  345.         do {
  346.             VDFastMemcpyPartial(dst2, src2, w);
  347.             dst2 += dststride;
  348.             src2 += srcstride;
  349.         } while(--h);
  350.     }
  351.     VDFastMemcpyFinish();
  352. }
  353.  
  354.