Page 4 of 5

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 3:32 pm
by Serge
Freeman wrote:Функцию 68.12 можно вызывать несколько раз?
Пока память не закончится.

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

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 4:10 pm
by johnfound
Ну, я кажется все таки сумел сделать все на ф.68.11
Несколько искусственно, но работает. Например чтобы держать част адресного пространство (1.5GB) я делаю так:

Code: Select all

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 не будут выделять от нее. Так ли это?

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 4:27 pm
by Serge
Есть решение проще: ф.68.26, в исходниках ядра - user_unmap. Функция освобождает физическую память в пределах ранее выделенного 68.11 блока. Размер блока и базовый адрес при этом сохраняется. Освобождённые страницы будут снова выделены ядром при первом обращении.

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 4:48 pm
by johnfound
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 = ?

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 5:12 pm
by Serge
ecx = block_base
edx = offset
esi = unmap_size

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 5:32 pm
by johnfound
Serge wrote:ecx = block_base
edx = offset
esi = unmap_size
Эсли правильно понял, эта функция проделает дыру в прежде выделенную память. А потом, как ее выделит снова, если понадобится?

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 6:30 pm
by Serge
Выделит ядро при первом обращении к странице. Механизм тот же что и для 68.11

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

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 7:00 pm
by johnfound
Теперь понятно. Спасибо.
Продолжаем дальше. :) А как лучше организовать мьютексы?

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 7:04 pm
by Serge

Code: Select all

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;
}


Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 7:50 pm
by johnfound
А что %1 и %2 означают? :shock:

Re: Вопросы по некоторых функциях...

Posted: Mon Oct 22, 2012 8:51 pm
by Serge
А что %1 и %2 означают
Наверное %0 и %1 ?
В данном случае %1 - временный регистр, %0 указатель на *val

Re: Вопросы по некоторых функциях...

Posted: Tue Oct 23, 2012 1:13 pm
by johnfound
Serge, шутник однако. :)
Вот в более вменяемом формате:

Code: Select all

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% пока ждет?

Re: Вопросы по некоторых функциях...

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

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

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

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

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

Re: Вопросы по некоторых функциях...

Posted: Tue Oct 23, 2012 2:01 pm
by johnfound
Мои тесты показывают что да, 100% не будет, но 10..20% вполне обычное дело. А нельзя ли сделать это через ф.23; И чтобы поток освобождающий мьютекс посылал бы событие первого из ожидающих. (наверное через ф.72?)

Re: Вопросы по некоторых функциях...

Posted: Tue Oct 23, 2012 7:16 pm
by johnfound
Есть ли другой метод получить TID текущего потока, чем ф.9 с ecx=-1?