| 346 | } |
| 347 | |
| 348 | SZ_PUBLIC void sz_move_serial(sz_ptr_t target, sz_cptr_t source, sz_size_t length) { |
| 349 | // Implementing `memmove` is trickier, than `memcpy`, as the ranges may overlap. |
| 350 | // Existing implementations often have two passes, in normal and reversed order, |
| 351 | // depending on the relation of `target` and `source` addresses. |
| 352 | // https://student.cs.uwaterloo.ca/~cs350/common/os161-src-html/doxygen/html/memmove_8c_source.html |
| 353 | // https://marmota.medium.com/c-language-making-memmove-def8792bb8d5 |
| 354 | // |
| 355 | // We can use the `memcpy` like left-to-right pass if we know that the `target` is before `source`. |
| 356 | // Or if we know that they don't intersect! In that case the traversal order is irrelevant, |
| 357 | // but older CPUs may predict and fetch forward-passes better. |
| 358 | if (target < source || target >= source + length) { |
| 359 | #if SZ_USE_MISALIGNED_LOADS |
| 360 | while (length >= 8) *(sz_u64_t *)target = *(sz_u64_t const *)(source), target += 8, source += 8, length -= 8; |
| 361 | #endif |
| 362 | while (length--) *(target++) = *(source++); |
| 363 | } |
| 364 | else { |
| 365 | // Jump to the end and walk backwards. |
| 366 | target += length, source += length; |
| 367 | #if SZ_USE_MISALIGNED_LOADS |
| 368 | while (length >= 8) *(sz_u64_t *)(target -= 8) = *(sz_u64_t const *)(source -= 8), length -= 8; |
| 369 | #endif |
| 370 | while (length--) *(--target) = *(--source); |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | #pragma endregion |
| 375 |
no outgoing calls
no test coverage detected
searching dependent graphs…