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
|
ssize_t
|
||||||
arch_cpu_user_strlcpy(char *to, const char *from, size_t size, addr_t *faultHandler)
|
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 %eax
|
||||||
popl %esi
|
popl %esi
|
||||||
ret
|
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
|
status_t
|
||||||
user_memcpy(void *to, const void *from, size_t size)
|
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
|
status_t
|
||||||
user_memset(void *s, char c, size_t count)
|
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
|
// #pragma mark - kernel public API
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user