asm optimized user_memcpy(), which should help somewhat, since the old version was a byte-by-byte copy.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20723 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -580,32 +580,6 @@ arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *faultHandler)
|
||||
{
|
||||
char *tmp = (char *)to;
|
||||
char *s = (char *)from;
|
||||
addr_t oldFaultHandler = *faultHandler;
|
||||
|
||||
// this check is to trick the gcc4 compiler and have it keep the error label
|
||||
if (to == NULL)
|
||||
goto error;
|
||||
|
||||
*faultHandler = (addr_t)&&error;
|
||||
|
||||
while (size--)
|
||||
*tmp++ = *s++;
|
||||
|
||||
*faultHandler = oldFaultHandler;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
*faultHandler = oldFaultHandler;
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
arch_cpu_user_strlcpy(char *to, const char *from, size_t size, addr_t *faultHandler)
|
||||
{
|
||||
|
||||
@@ -219,3 +219,46 @@ FUNCTION(arch_debug_save_registers):
|
||||
popl %eax
|
||||
popl %esi
|
||||
ret
|
||||
|
||||
/* status_t arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */
|
||||
FUNCTION(arch_cpu_user_memcpy):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
movl 12(%esp),%edi /* dest */
|
||||
movl 16(%esp),%esi /* source */
|
||||
movl 20(%esp),%ecx /* count */
|
||||
|
||||
/* set the fault handler */
|
||||
movl 24(%esp),%edx /* fault handler */
|
||||
movl (%edx),%eax
|
||||
movl $.L_user_memcpy_error, (%edx)
|
||||
|
||||
/* move by words */
|
||||
cld
|
||||
shrl $2,%ecx
|
||||
rep
|
||||
movsl
|
||||
|
||||
/* move any remaining data by bytes */
|
||||
movl 20(%esp),%ecx
|
||||
andl $3,%ecx
|
||||
rep
|
||||
movsb
|
||||
|
||||
/* restore the old fault handler */
|
||||
movl %eax,(%edx)
|
||||
xor %eax,%eax
|
||||
|
||||
popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
|
||||
/* error condition */
|
||||
.L_user_memcpy_error:
|
||||
/* restore the old fault handler */
|
||||
movl %eax,(%edx)
|
||||
movl $-1,%eax /* return a generic error, the wrapper routine will deal with it */
|
||||
popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
|
||||
|
||||
@@ -3741,7 +3741,9 @@ test_lock_memory(vm_address_space *addressSpace, addr_t address,
|
||||
status_t
|
||||
user_memcpy(void *to, const void *from, size_t size)
|
||||
{
|
||||
return arch_cpu_user_memcpy(to, from, size, &thread_get_current_thread()->fault_handler);
|
||||
if (arch_cpu_user_memcpy(to, from, size, &thread_get_current_thread()->fault_handler) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -3765,10 +3767,11 @@ user_strlcpy(char *to, const char *from, size_t size)
|
||||
status_t
|
||||
user_memset(void *s, char c, size_t count)
|
||||
{
|
||||
return arch_cpu_user_memset(s, c, count, &thread_get_current_thread()->fault_handler);
|
||||
if (arch_cpu_user_memset(s, c, count, &thread_get_current_thread()->fault_handler) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - kernel public API
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user