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:
parent
9e082fcb68
commit
464f31a53b
3 changed files with 49 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue