Board.KolibriOS.org

Official KolibriOS board
It is currently Fri Sep 25, 2020 7:29 am

All times are UTC+03:00




Post new topic  Reply to topic  [ 66 posts ]  Go to page Previous 1 2 3 4 5 Next
Author Message
PostPosted: Mon Oct 22, 2012 3:32 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Freeman wrote:
Функцию 68.12 можно вызывать несколько раз?
Пока память не закончится.

johnfound
На brk()/sbrk() управление памятью не заканчивается.
Есть достаточное количество алгоритмов malloc на основе VirtualAlloc() или mmap() например вездесущая dlmalloc.


Top
   
PostPosted: Mon Oct 22, 2012 4:10 pm 
Offline

Joined: Fri Feb 18, 2011 3:13 pm
Posts: 201
Ну, я кажется все таки сумел сделать все на ф.68.11
Несколько искусственно, но работает. Например чтобы держать част адресного пространство (1.5GB) я делаю так:
Code:
MAX_HEAP_SIZE = $60000000
proc mem.realloc_heap, .heapptr, .newsize, .oldsize
begin
        push    eax ebx ecx edx

        mov     eax, sys_f68
        mov     ebx, 20
        mov     ecx, [.newsize]
        mov     edx, [__ptrHeapStart]
        int     $40

        mov     eax, sys_f68
        mov     ebx, 20
        mov     ecx, MAX_HEAP_SIZE
        mov     edx, [__ptrHeapStart]
        int     $40

        cmp     eax, [__ptrHeapStart]
        jne     .error

        pop     edx ecx ebx eax
        return

.error:
        int3
endp


Надеюсь при этом, что физическая память над [.newsize] будет освобождена, но последующие 68.12 не будут выделять от нее. Так ли это?


Top
   
PostPosted: Mon Oct 22, 2012 4:27 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Есть решение проще: ф.68.26, в исходниках ядра - user_unmap. Функция освобождает физическую память в пределах ранее выделенного 68.11 блока. Размер блока и базовый адрес при этом сохраняется. Освобождённые страницы будут снова выделены ядром при первом обращении.


Top
   
PostPosted: Mon Oct 22, 2012 4:48 pm 
Offline

Joined: Fri Feb 18, 2011 3:13 pm
Posts: 201
Serge wrote:
Есть решение проще: ф.68.26, в исходниках ядра - user_unmap. Функция освобождает физическую память в пределах ранее выделенного 68.11 блока. Размер блока и базовый адрес при этом сохраняется.


Возможно, только несколько загадочно:
Wiki wrote:
Подфункция 26 - user_unmap

New SVN revision #2400 by Serge in /kernel/trunk/core: new 68.26 user_unmap(void* block_base, unsigned int offset, size_t unmap_size);


Параметры:

eax = 68 - номер функции
ebx = 26 - номер подфункции
ecx = ?
edx = ?
esi = ?


Top
   
PostPosted: Mon Oct 22, 2012 5:12 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
ecx = block_base
edx = offset
esi = unmap_size


Top
   
PostPosted: Mon Oct 22, 2012 5:32 pm 
Offline

Joined: Fri Feb 18, 2011 3:13 pm
Posts: 201
Serge wrote:
ecx = block_base
edx = offset
esi = unmap_size


Эсли правильно понял, эта функция проделает дыру в прежде выделенную память. А потом, как ее выделит снова, если понадобится?


Top
   
PostPosted: Mon Oct 22, 2012 6:30 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Выделит ядро при первом обращении к странице. Механизм тот же что и для 68.11

Сама 68.11 не рассчитана на слишком активное использование. Она основа для malloc в обычных приложениях. Но если требуется выделять и освобождать большие объёмы данных (графические редакторы, базы данных, игры ) лучше использовать специально написанные аллокаторы. В этом случае 68.26 позволяет организовать очень гибкое управление памятью на уровне приложения и возвращать ядру неиспользуемую в данный момент физическую память.


Top
   
PostPosted: Mon Oct 22, 2012 7:00 pm 
Offline

Joined: Fri Feb 18, 2011 3:13 pm
Posts: 201
Теперь понятно. Спасибо.
Продолжаем дальше. :) А как лучше организовать мьютексы?


Top
   
PostPosted: Mon Oct 22, 2012 7:04 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Code:
void mutex_lock(volatile uint32_t *val)
{
    uint32_t tmp;

    __asm__ __volatile__ (
"0:\n\t"
    "mov %0, %1\n\t"
    "testl %1, %1\n\t"
    "jz 1f\n\t"

    "movl $68, %%eax\n\t"
    "movl $1,  %%ebx\n\t"
    "int  $0x40\n\t"
    "jmp 0b\n\t"
"1:\n\t"
    "incl %1\n\t"
    "xchgl %0, %1\n\t"
    "testl %1, %1\n\t"
    "jnz 0b\n"
    : "+m" (*val), "=&r"(tmp)
    ::"eax","ebx" );
}

static inline void mutex_unlock(volatile uint32_t *val)
{
    *val = 0;
}



Top
   
PostPosted: Mon Oct 22, 2012 7:50 pm 
Offline

Joined: Fri Feb 18, 2011 3:13 pm
Posts: 201
А что %1 и %2 означают? :shock:


Top
   
PostPosted: Mon Oct 22, 2012 8:51 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Quote:
А что %1 и %2 означают

Наверное %0 и %1 ?
В данном случае %1 - временный регистр, %0 указатель на *val


Top
   
PostPosted: Tue Oct 23, 2012 1:13 pm 
Offline

Joined: Fri Feb 18, 2011 3:13 pm
Posts: 201
Serge, шутник однако. :)
Вот в более вменяемом формате:
Code:
proc mutex_lock, .ptrMutex
begin
        push    ebx ecx esi
        mov     esi, [.ptrMutex]

.loop:
        mov     ecx, [esi]
        test    ecx, ecx
        jz      .free

        mov     eax, 68
        mov     ebx, 1
        int     $40
        jmp     .loop

.free:
        inc     ecx
        xchg    ecx, [esi]
        test    ecx, ecx
        jnz     .loop

        pop     esi ecx ebx
        return
endp


А не будет ли эта функция загружать CPU на 100% пока ждет?


Top
   
PostPosted: Tue Oct 23, 2012 1:17 pm 
johnfound wrote:
А не будет ли эта функция загружать CPU на 100% пока ждет?

68.1 сильно снижает нагрузку, так что нет, 100% не будет и даже близко к 1% не будет.

http://wiki.kolibrios.org/wiki/SysFn68/ru
Spoiler: Show
Подфункция 1 - переключиться на следующий поток выполнения.

Функция завершает текущий квант времени, выделенный потоку, и переключается на следующий. (Какой поток какого процесса будет следующим, предсказать нельзя). Позднее, когда до текущего потока дойдёт очередь, выполнение возобновится.

Параметры:
eax = 68 - номер функции
ebx = 1 - номер подфункции

Возвращаемое значение:
функция не возвращает значения


Top
   
PostPosted: Tue Oct 23, 2012 2:01 pm 
Offline

Joined: Fri Feb 18, 2011 3:13 pm
Posts: 201
Мои тесты показывают что да, 100% не будет, но 10..20% вполне обычное дело. А нельзя ли сделать это через ф.23; И чтобы поток освобождающий мьютекс посылал бы событие первого из ожидающих. (наверное через ф.72?)


Top
   
PostPosted: Tue Oct 23, 2012 7:16 pm 
Offline

Joined: Fri Feb 18, 2011 3:13 pm
Posts: 201
Есть ли другой метод получить TID текущего потока, чем ф.9 с ecx=-1?


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 66 posts ]  Go to page Previous 1 2 3 4 5 Next

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Limited