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

Applications development, KoOS API questions
  • Ну, я кажется все таки сумел сделать все на ф.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 не будут выделять от нее. Так ли это?
  • Есть решение проще: ф.68.26, в исходниках ядра - user_unmap. Функция освобождает физическую память в пределах ранее выделенного 68.11 блока. Размер блока и базовый адрес при этом сохраняется. Освобождённые страницы будут снова выделены ядром при первом обращении.
  • 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 = ?
  • ecx = block_base
    edx = offset
    esi = unmap_size
  • Serge wrote:ecx = block_base
    edx = offset
    esi = unmap_size
    Эсли правильно понял, эта функция проделает дыру в прежде выделенную память. А потом, как ее выделит снова, если понадобится?
  • Выделит ядро при первом обращении к странице. Механизм тот же что и для 68.11

    Сама 68.11 не рассчитана на слишком активное использование. Она основа для malloc в обычных приложениях. Но если требуется выделять и освобождать большие объёмы данных (графические редакторы, базы данных, игры ) лучше использовать специально написанные аллокаторы. В этом случае 68.26 позволяет организовать очень гибкое управление памятью на уровне приложения и возвращать ядру неиспользуемую в данный момент физическую память.
  • Теперь понятно. Спасибо.
    Продолжаем дальше. :) А как лучше организовать мьютексы?
  • 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;
    }
    
    
  • А что %1 и %2 означают? :shock:
  • А что %1 и %2 означают
    Наверное %0 и %1 ?
    В данном случае %1 - временный регистр, %0 указатель на *val
  • 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% пока ждет?
  • johnfound wrote:А не будет ли эта функция загружать CPU на 100% пока ждет?
    68.1 сильно снижает нагрузку, так что нет, 100% не будет и даже близко к 1% не будет.

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

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

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

    Возвращаемое значение:
    функция не возвращает значения
  • Мои тесты показывают что да, 100% не будет, но 10..20% вполне обычное дело. А нельзя ли сделать это через ф.23; И чтобы поток освобождающий мьютекс посылал бы событие первого из ожидающих. (наверное через ф.72?)
  • Есть ли другой метод получить TID текущего потока, чем ф.9 с ecx=-1?
  • Who is online

    Users browsing this forum: No registered users and 6 guests