optimize the system call fork

- add a function to copy a physical page
=> reduce the using of vm_alloc and vm_free
This commit is contained in:
Stefan Lankes 2011-03-03 09:13:00 +01:00
parent 9e082fcb68
commit 464f31a53b
3 changed files with 49 additions and 17 deletions

View file

@ -18,8 +18,13 @@
extern "C" {
#endif
/*
* This function copies a physical page to its new physical destination.
*/
void copy_page_physical(void* dest, const void * src);
#ifdef HAVE_ARCH_MEMCPY
inline static void *memcpy(void *dest, const void *src, size_t count)
inline static void *memcpy(void* dest, const void *src, size_t count)
{
int32_t i, j, k;
@ -39,7 +44,7 @@ inline static void *memcpy(void *dest, const void *src, size_t count)
#endif
#ifdef HAVE_ARCH_MEMSET
inline static void *memset(void *dest, int val, size_t count)
inline static void *memset(void* dest, int val, size_t count)
{
int32_t i, j;
@ -55,7 +60,7 @@ inline static void *memset(void *dest, int val, size_t count)
#endif
#ifdef HAVE_ARCH_STRLEN
inline static size_t strlen(const char *str)
inline static size_t strlen(const char* str)
{
size_t len = 0;
uint32_t i, j;
@ -73,11 +78,11 @@ inline static size_t strlen(const char *str)
#endif
#ifdef HAVE_ARCH_STRNCPY
char* strncpy(char *dest, const char *src, size_t n);
char* strncpy(char* dest, const char* src, size_t n);
#endif
#ifdef HAVE_ARCH_STRCPY
char* strcpy(char *dest, const char *src);
char* strcpy(char* dest, const char* src);
#endif
#ifdef __cplusplus

View file

@ -60,4 +60,39 @@ L3:
pop ebp
ret
; The following function based on JamesM's kernel development tutorials
; (http://www.jamesmolloy.co.uk/tutorial_html/)
global copy_page_physical
copy_page_physical:
push ebx ; According to __cdecl, we must preserve the contents of EBX.
pushf ; push EFLAGS, so we can pop it and reenable interrupts
; later, if they were enabled anyway.
cli ; Disable interrupts, so we aren't interrupted.
; Load these in BEFORE we disable paging!
mov ebx, [esp+16] ; Source address
mov ecx, [esp+12] ; Destination address
mov edx, cr0 ; Get the control register...
and edx, 0x7fffffff ; and...
mov cr0, edx ; Disable paging.
mov edx, 1024 ; 1024*4bytes = 4096 bytes
.loop:
mov eax, [ebx] ; Get the word at the source address
mov [ecx], eax ; Store it at the dest address
add ebx, 4 ; Source address += sizeof(word)
add ecx, 4 ; Dest address += sizeof(word)
dec edx ; One less word to do
jnz .loop
mov edx, cr0 ; Get the control register again
or edx, 0x80000000 ; and...
mov cr0, edx ; Enable paging.
popf ; Pop EFLAGS back.
pop ebx ; Get the original value of EBX back.
ret
SECTION .note.GNU-stack noalloc noexec nowrite progbits

View file

@ -84,27 +84,19 @@ inline static size_t copy_page_table(uint32_t pgd_index, page_table_t* pgt, int*
(*counter)++;
for(i=0; i<1024; i++) {
if (pgt->entries[i]) {
if (pgt->entries[i] & 0xFFFFF000) {
phyaddr = get_page();
if (!phyaddr)
continue;
if (counter)
(*counter)++;
viraddr = map_region(0, phyaddr, 1, MAP_KERNEL_SPACE);
if (!viraddr) {
put_page(phyaddr);
continue;
}
memcpy((void*) viraddr, (void*) ((pgd_index << 22) | (i << 12)), PAGE_SIZE);
copy_page_physical((void*)phyaddr, (void*) (pgt->entries[i] & 0xFFFFF000));
new_pgt->entries[i] = phyaddr | (pgt->entries[i] & 0xFFF);
// only the child use the copy => unmap copy
if (!vm_free(viraddr, 1))
atomic_int32_sub(&curr_task->mem_usage, 1);
// only the child use the copy
atomic_int32_sub(&curr_task->mem_usage, 1);
}
}