]> git.sesse.net Git - casparcg/blobdiff - common/memory/memcpy.h
2.0.2: memcpy: Added alignment check for safety.
[casparcg] / common / memory / memcpy.h
index 7168878ab60ada52c749194314efb923a7cfc48e..57ab081e0b1920f1ae973855323e9ea43feac922 100644 (file)
@@ -1,3 +1,22 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
 #pragma once\r
 \r
 #include <assert.h>\r
@@ -10,7 +29,6 @@ namespace internal {
 \r
 static void* fast_memcpy(void* dest, const void* source, size_t count)\r
 {\r
-       assert(count % (16*8) == 0);\r
        assert(dest != nullptr);\r
        assert(source != nullptr);\r
 \r
@@ -53,14 +71,24 @@ static void* fast_memcpy(void* dest, const void* source, size_t count)
 \r
 }\r
 \r
-static void* fast_memcpy(void* dest, const void* source, size_t num)\r
+static void* fast_memcpy(void* dest, const void* source, size_t count)\r
 {   \r
-       tbb::affinity_partitioner partitioner;\r
-       tbb::parallel_for(tbb::blocked_range<size_t>(0, num/128), [&](const tbb::blocked_range<size_t>& r)\r
+       if((reinterpret_cast<int>(source) & 15) || (reinterpret_cast<int>(dest) & 15))\r
+               return memcpy(dest, source, count);\r
+\r
+       if(count < 2048)\r
+               return memcpy(dest, source, count);\r
+\r
+       size_t rest = count % 128;\r
+       count -= rest;\r
+\r
+       tbb::affinity_partitioner ap;\r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, count/128), [&](const tbb::blocked_range<size_t>& r)\r
        {       \r
                internal::fast_memcpy(reinterpret_cast<char*>(dest) + r.begin()*128, reinterpret_cast<const char*>(source) + r.begin()*128, r.size()*128);   \r
-       }, partitioner);   \r
-       return dest;\r
+       }, ap);\r
+\r
+       return memcpy(reinterpret_cast<char*>(dest)+count,  reinterpret_cast<const char*>(source)+count, rest);\r
 }\r
 \r
 \r