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

Applications development, KoOS API questions
  • Да, теперь ясно почему все работает. Только мне это все равно не помогает, потому что ф.68.11 я не могу использовать совсем. Мне нужна ф.64, а стеки надо выделять из общей кучи, а там процедуры.
    Все таки мне кажеться что сумею выкрутится... :)
  • johnfound
    Почему не подходит ф.68.11 ?

    Кстати ф.64 и 68.11 взаимно несовместимы. Загрузка DLL и некоторые функции ядра неявно вызывают 68.11 после чего ф.64 перестаёт работать. Это надо учитывать.
  • Serge wrote:johnfound
    Почему не подходит ф.68.11 ?
    Кстати ф.64 и 68.11 взаимно несовместимы. Загрузка DLL и некоторые функции ядра неявно вызывают 68.11 после чего ф.64 перестаёт работать. Это надо учитывать.
    Потому что realloc (68.20) меняет адрес блока памяти, а менаджеру кучи FreshLib нужно чтобы базовой адрес блока оставался неизменным - иначе все ранее выделенные динамические переменные будут перемещены. Нельзя ли сделать чтобы базовой адрес оставался тот что указан в edx?
    А то что некоторые функции ядра вызывают 68.11, очень плохо... А какие кроме загрузка DLL (68.19)?
  • johnfound wrote:Потому что realloc (68.20) меняет адрес блока памяти, а менаджеру кучи FreshLib нужно чтобы базовой адрес блока оставался неизменным - иначе все ранее выделенные динамические переменные будут перемещены.
    Задавать смещением от базы, НЕ?
  • Нельзя. Память из этой кучи выделяется приложению и оно ожидает что все блоки будут оставаться по местам. Если на некотором етапе место не хватает, менeджер кучи запрашивает увеличения блока. Эсли блок при этом переместится, ранее выделенные указатели будут уже невалидные и преизчислить их новое значение нет возможности, потому что неизвестно где они и кто с ним работает. Это как HealAlloc в Win32 или malloc в C.
    Лучше всего было бы если можно было заблокировать адресное пространсво для ф.64, а ф68.11 работала после него. Например с 0 по $3fffffff - ф64, а с $40000000 по $7fffffff - ф68. Тогда было бы место для кучи, а стеки выделялись бы через 68.12 - что несомнено удобнее.
  • Что то я не вкуриваю - либо тут какой то говнокод уже совсем пошел, либо ты сам не понял чего то. Все должно быть решаемо, масштабируемо и подстраиваемо. Пока же наблюдается создавание себе любимым трудностей и героическое их преодолевание.
  • Mario, мне конечно многое еще не ясно. Поэтому и спрашиваю.
    Попробую объяснить большую картинку:
    1. Я занялся портирования FreshLib в Колибри.
    2. Все функции FreshLib на все платформы должны работать одинаково - в Win32, Linux и KolibriOS.
    3. FreshLib широко и повсюду использует динамические переменные которые выделяются через менеджер кучи. В Win32 используются HealAlloc и компания; В Linux можно malloc из libC, а можно и менеджер кучи из FASMLIB vid-a; В Колибри можно только менеджер vid-а, потому что в Колибри нет системный менеджер кучи ( ф68.11 не есть менеджер кучи, потому что может выделять только целые страницы).
    4. Для нормальной работой менеджера кучи, ему нужен блок памяти которой начинал бы всегда в одном месте, а его размер можно было менять - увеличивать и уменьшать. Ф.64 подходит для этого идеально. (я кстати в Linux использую sys_brk)
    5. В FreshLib еще имеются функции для работой с потоками. В Колибри, чтобы создать поток, ему надо выделить память для стека. Эта память в Колибри лучше чего выделяется ф.68.11.
    6. Выходит, что нельзя реализовать т.4 и т.5 одновременно. Как быть? Что посоветуешь?
  • ЕМНИП для ф. 64 в свое время писались аж два прикладных менеджера памяти. Я тогда это не использовал, да и вообще мало кто использовал. Потом нужда вообще отпала с внедрением ф.68.
    johnfound wrote:4. Для нормальной работой менеджера кучи, ему нужен блок памяти которой начинал бы всегда в одном месте, а его размер можно было менять - увеличивать и уменьшать. Ф.64 подходит для этого идеально. (я кстати в Linux использую sys_brk)
    А что мешает все таки начать с указателя на область памяти, который используется собственно менеджером кучи? Просто добавится еще одна операция в вычислении адреса.
  • Mario, представь что 68.12 выделила блок от $1000, размером в 4096 байт для кучи.
    Процедура А запрашивает 32 байта на переменную, и ее выделяются 32 байт от адрес $1000
    Она запоминает этот адрес ($1000) в переменную и потом каждой раз когда выполняется, она считает этот адрес и работает с нем.
    Потом процедура 2 запрашивает 4096 байт. Но блок (размер 4096 - 32) меньше этого запроса!
    Менеджер кучи, используя 68.20 меняет размер блока на 8192. Теперь он начинается с $2000 и имеет размер 8192.
    Менеджер выделяет процедуре Б 4096 байт с адреса $2020 (потому что первые 32 байта выделены процедуре А).
    Но процедура А совершенно не знает что весь блок теперь начинается с $2000 и по прежнему продолжает работать с $1000.

    Code: Select all

    call A
    call Б
    call A  ; GPF, память на $1000 нету уже.
    
  • Пусть процедуры каждый раз берут указатели из изначального куска адрес которого не меняется, но меняются указатели в нем размещенные. Список списков.

    И вообще зачем настолько извращаться пытаясь разместить на одной реальной странице две или более виртуальные-логические? Потери не так существенны. Не нужно создавать себе проблемы лишние. Да, будет определенный процент потерь, но это же не страницы размером в 4 Мб! Это всего лишь 4 Кб!

    З.Ы. Еще я нифига не понял почему две процедуры лезут в один и тот же кусок, как в этом случае многопоточность будет синхронизирована? Если через мьютексы, то резон от такой многопоточности невелик.
  • Mario, наверное читаешь через строку. Нельзя так сделать. Ну совсем нельзя! Я пишу библиотеку, а не программу для Колибри. И библиотека эта надо работать в Windows и Linux кроме в Колибри. И надо быть совместимой. Приложение написано с использования FreshLib надо работать в Windows, Linux и Колибри совершенно одинаковым образом. И я совершенно не намерен менять API только потому что в Колибри нельзя сделать так или иначе. Если говорю что адреса нельзя менять, значит это именно так. Никакие "списки списков" нельзя делать.
  • Портирование без переделки редко обходится. В данном случае я не знаю других способов решения. Если кто то другой (более умный и способный) даст более приемлемое решение, то это будет хорошо. Я же в данном специфическом случае более ничего предложить не могу.
  • Mario wrote:Портирование без переделки редко обходится.
    А у меня выходит. По крайней мере в Windows и Linux все компилируется с одного файла, меняя только TargetOS. Вот например как выглядит одна и та же программа под Linux ( на переднем плане) и Windows (на заднем):
    Image

    А потом будет то же самое и под Колибри. ;)
  • johnfound
    Мне кажется, что нужно рассматривать семейство подфункций 68 как аналог VirtualAlloc в Windows, а совсем не как HeapAlloc. И делать примерно так же, как делает FastMM: запрашивать сразу большие блоки, как-то у себя хранить служебку и цепочки, и уже самостоятельно выдавать неизменные указатели программе.

    Функцию 68.12 можно вызывать несколько раз?
  • Who is online

    Users browsing this forum: No registered users and 5 guests