Applications development, KoOS API questions
-
-
- Posts 3952
- Joined: Wed Mar 08, 2006 6:25 pm
Freeman wrote:Функцию 68.12 можно вызывать несколько раз?
Пока память не закончится.
johnfound
На brk()/sbrk() управление памятью не заканчивается.
Есть достаточное количество алгоритмов malloc на основе VirtualAlloc() или mmap() например вездесущая
dlmalloc.
-
- Posts 201
- Joined: Fri Feb 18, 2011 3:13 pm
Ну, я кажется все таки сумел сделать все на ф.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 не будут выделять от нее. Так ли это?
-
- Posts 3952
- Joined: Wed Mar 08, 2006 6:25 pm
Есть решение проще: ф.68.26, в исходниках ядра - user_unmap. Функция освобождает физическую память в пределах ранее выделенного 68.11 блока. Размер блока и базовый адрес при этом сохраняется. Освобождённые страницы будут снова выделены ядром при первом обращении.
-
- Posts 201
- Joined: Fri Feb 18, 2011 3:13 pm
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 = ?
-
- Posts 3952
- Joined: Wed Mar 08, 2006 6:25 pm
ecx = block_base
edx = offset
esi = unmap_size
-
- Posts 201
- Joined: Fri Feb 18, 2011 3:13 pm
Serge wrote:ecx = block_base
edx = offset
esi = unmap_size
Эсли правильно понял, эта функция проделает дыру в прежде выделенную память. А потом, как ее выделит снова, если понадобится?
-
- Posts 3952
- Joined: Wed Mar 08, 2006 6:25 pm
Выделит ядро при первом обращении к странице. Механизм тот же что и для 68.11
Сама 68.11 не рассчитана на слишком активное использование. Она основа для malloc в обычных приложениях. Но если требуется выделять и освобождать большие объёмы данных (графические редакторы, базы данных, игры ) лучше использовать специально написанные аллокаторы. В этом случае 68.26 позволяет организовать очень гибкое управление памятью на уровне приложения и возвращать ядру неиспользуемую в данный момент физическую память.
-
- Posts 201
- Joined: Fri Feb 18, 2011 3:13 pm
Теперь понятно. Спасибо.
Продолжаем дальше.
А как лучше организовать мьютексы?
-
- Posts 3952
- Joined: Wed Mar 08, 2006 6:25 pm
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;
}
-
- Posts 201
- Joined: Fri Feb 18, 2011 3:13 pm
А что %1 и %2 означают?
-
- Posts 3952
- Joined: Wed Mar 08, 2006 6:25 pm
А что %1 и %2 означают
Наверное %0 и %1 ?
В данном случае %1 - временный регистр, %0 указатель на *val
-
- Posts 201
- Joined: Fri Feb 18, 2011 3:13 pm
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 - номер подфункции
Возвращаемое значение:
функция не возвращает значения
-
- Posts 201
- Joined: Fri Feb 18, 2011 3:13 pm
Мои тесты показывают что да, 100% не будет, но 10..20% вполне обычное дело. А нельзя ли сделать это через ф.23; И чтобы поток освобождающий мьютекс посылал бы событие первого из ожидающих. (наверное через ф.72?)
-
- Posts 201
- Joined: Fri Feb 18, 2011 3:13 pm
Есть ли другой метод получить TID текущего потока, чем ф.9 с ecx=-1?