OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Суббота, 27 Апрель, 2024 20:18

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
СообщениеДобавлено: Пятница, 14 Июль, 2023 17:49 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
проезжая мимо станции, предлагаю в линуксовом HostKernel, в `AllocateClusterMem()` заменить `65536` на нолик в `mmap()`.

rationale: это, похоже, была попытка заюзать «дырку» перед образом бинаря (там около двух мегов дырочка). смысла в этом нет никакого, а вот небольшой вред есть. вред такой: сборщик мусора сканирует стек на предмет чего-то, похожего на адреса. он отбрасывает всё, что перед первым кластером, и всё, что после последнего. но! если первое выделение в самом начале памяти, а последнее близко к концу (ядро выделяет странички с конца адресного пространства), то почти никакое значение из стека не отбрасывается, хотя большинство из них не указатели. (в смысле, отбрасываются только по выравниванию.)

короче. эта дырка в начале никакой роли не играет, и смысла пытаться её занять нет. зато сканеру стека значительно полегчает. оно, конечно, мелочь на общем фоне — но зачем же. ведь это же очень и очень!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 27 Июль, 2023 14:03 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3778
arisu писал(а):
проезжая мимо станции, предлагаю в линуксовом HostKernel, в `AllocateClusterMem()` заменить `65536` на нолик в `mmap()`.

rationale: это, похоже, была попытка заюзать «дырку» перед образом бинаря (там около двух мегов дырочка). смысла в этом нет никакого, а вот небольшой вред есть. вред такой: сборщик мусора сканирует стек на предмет чего-то, похожего на адреса. он отбрасывает всё, что перед первым кластером, и всё, что после последнего. но! если первое выделение в самом начале памяти, а последнее близко к концу (ядро выделяет странички с конца адресного пространства), то почти никакое значение из стека не отбрасывается, хотя большинство из них не указатели. (в смысле, отбрасываются только по выравниванию.)

короче. эта дырка в начале никакой роли не играет, и смысла пытаться её занять нет. зато сканеру стека значительно полегчает. оно, конечно, мелочь на общем фоне — но зачем же. ведь это же очень и очень!

Вы у себя как-то это уверенно протестировали в сборке на Linux?

Попробую поспрашивать Александра про этот момент, тут есть такой промежуток для стека сигналов, может это надо было для этого...
Код:
sigStackSize = MAX(Libc.SIGSTKSZ, 65536);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 27 Июль, 2023 17:31 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
Иван Денисов писал(а):
Вы у себя как-то это уверенно протестировали в сборке на Linux?
да. я довольно плотно занимался ядром и mm/gc в эти недели, так что тут я не просто гадаю, я даже понимаю, что это, как работает, зачем и куда. ;-) Большой Грызь теперь понимать как работать маленький ядро.

Иван Денисов писал(а):
тут есть такой промежуток для стека сигналов, может это надо было для этого...
Код:
sigStackSize = MAX(Libc.SIGSTKSZ, 65536);
нет, это совсем другое. просто размер стека для обработчика сигналов, который выделяется вот так: `sigStack := Libc.calloc(1, sigStackSize);` (что довольно забавно; щаз проснусь и заменю на mmap; и вот тут, кстати, как раз можно заюзать начало памяти).

кстати, и безопасную выгрузку модулей можно без особого труда забрать. и ещё починить обработку ^C. да и менеджер кластеров у меня теперь получше будет. в общем, я там неплохо потоптался. все изменения, конечно, сразу же после тестов и коммитов идут в мою рабочую систему. кое-что на этом реально крутится неделями, так что в дополнение к тому, что я понимаю изменения, ещё и полевые тесты. ;-)

это я всё в том смысле, что: «да, последний зуб даю!» ;-)

p.s.: вообще, я там поставил нолик весьма давно, несколько месяцев назад уж. тогда со смутным пониманием, сейчас с полным.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 27 Июль, 2023 18:33 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3778
Александр сказал, что если указывать 0, то иногда выделяются отрицательные адреса памяти, и тогда ББ на линуксе ведёт себя некорректно. Как вы эту проблему у себя решили?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 27 Июль, 2023 18:58 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
Иван Денисов писал(а):
Александр сказал, что если указывать 0, то иногда выделяются отрицательные адреса памяти, и тогда ББ на линуксе ведёт себя некорректно. Как вы эту проблему у себя решили?

а это тоже не решение: как только дырка в начале памяти занята (сразу, то бишь) — ядро (которое линукс) мгновенно ревертится на обычный метод выделения, который зависит от многих параметров (а вот от желаемого адреса обычно не зависит вообще). в частности, на моей системе mmap всегда получает страницы начиная с конца памяти, и все адреса всегда отрицательные. сканеру, тащемта, совершенно всё равно, лишь бы кластер не пересёк границу 08000_0000H, тогда нормально работает. знаковое сравнение работает правильно, пока оба адреса одного знака (любое отрицательное ведь всегда меньше 0FFFF_FFFFH). этот факт омики активно используют. а для надёжности можно просто на старте забить область по адресу смены знака, и всё.

вообще, с этими знаками там везде сплошные проблемы, и работает оно на честном слове и молитвах. у меня это решено радикально, введением типа `SYSTEM.ADDRESS`, который как раз беззнаковый. но на самом деле оно работало ещё до этого; а хак с 64К не спасал вообще никак.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 27 Июль, 2023 20:29 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3778
Падать оно падало. Может у вас не падает, так как решили проблему иначе.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 27 Июль, 2023 21:18 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
я ж говорю, что убрал это задолго до того, как переделывал kernel на беззнаковые адреса. собственно, посмотрите код kernel, там довольно прозрачно всё (условия циклов и сортировок, не обязательно глубоко вникать). падать оно и может, и будет когда выделено много памяти, и знаки адресов начала и конца какого-то кластера не совпадают. а если знаки совпадают, то сравнения работают как задумано (потому что сканирование идёт по кластерам, и сравнения используются только для определения попадания адреса в границы кластера).

ну это… я же вам говорю, что на моей системе mmap при занятом запрашиваемом адресе всегда выделяет страницы начиная с конца. что никак не помешало оригиналу нормально работать ещё в самом начале года, когда я вообще ничего там не менял и просто запускал. а сканер стека в итоге просто считает всю память занятой, потому что минимальный адрес минимальный отрицательный, а максимальный — максимально положительный. там, в общем, получается корректный wraparound. список кластеров всегда отсортирован по возрастанию начального адреса, так что пока какой-то кластер не пересекает магическую границу 08000_0000H — всё работает.

более того, даже выравнивание очевидно работает правильно:
`(-10 + 3) DIV 4 * 4` — даёт вполне корректное `-8` (выравнивая по направлению к концу памяти).

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Пятница, 28 Июль, 2023 09:51 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3778
Есть какой-то тест у Александра, заменим, попробуем.

arisu писал(а):
и в любом случае вашему варианту ядра необходимо на старте зарезервировать область памяти (две странички), пересекающую волшебную границу смены знака. иначе при большом потреблении памяти будут волшебные слабо повторимые баги.

Спасибо за совет. Всё, что повышает стабильность работы надо применить! А как это зарезервировать именно в этом месте?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Пятница, 28 Июль, 2023 17:07 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
как-то типа такого:
Код:
adr := Libc.mmap(08000_0000H - pageSize, pageSize, Libc.PROT_NONE, Libc.MAP_PRIVATE + Libc.MAP_ANON, -1, 0);
IF (adr # Libc.MAP_FAILED) & (adr # 08000_0000H - pageSize) THEN
  _ := Libc.munmap(adr, pageSize)
END;
adr := Libc.mmap(08000_0000H, pageSize, Libc.PROT_NONE, Libc.MAP_PRIVATE + Libc.MAP_ANON, -1, 0);
IF (adr # Libc.MAP_FAILED) & (adr # 08000_0000H) THEN
  _ := Libc.munmap(adr, pageSize)
END;

просто просим у системы две странички на «плохих адресах». если какая-то выделилась в другом месте — ура, нам повезло, плохой адрес уже занят, возвращаем страничку обратно.

теперь мы не сможем выделить больше двух гигабайт памяти одним куском (в смысле, одним NEW) — но это всё равно не работало никогда (ядро не позволит, там проверка на переполнение есть). зато и не получим «опасного» кластера.

берём странички по отдельности, а не сразу две мы затем, что если просить две, и кто-то уже съел 08000_0000H и дальше, например — то ядро нам даст память в другом месте, и страница перед переходом знака останется без защиты. а там защита нужна, потому что код в Kernel считает конечный адрес для проверок за концом кластера, и использует `<`. если не защитить — то конечный адрес может врапнуться в минус. `08000_0000H` в принципе-то можно и не защищать, но это стрёмное число, лучше его в коде избегать. бережённого, так сказать…

`pageSize` уже в коде есть. добавить это надо прямо в Init, в любое место после определения `pageSize`.

p.p.s.: короче, отредактировал код в Правильно и Надёжно, прошлый плохой был.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Среда, 02 Август, 2023 19:38 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
Иван Денисов писал(а):
Есть какой-то тест у Александра, заменим, попробуем.
Код:
MODULE TestKernel_2;

   IMPORT Kernel, Log;

   CONST
      r1Size = 16; r2Size = 64 * 1024; r3Size = 1024 * 1024;
      a1Size = 16; a2Size = 64 * 1024; a3Size = 1024 * 1024;

   TYPE
      Item = POINTER TO RECORD
         next: Item;
         p1: Item1; p2: Item2; p3: Item3;
         a1, a2, a3: POINTER TO ARRAY OF INTEGER
      END;
      
      Item1 = POINTER TO RECORD
         x: ARRAY r1Size DIV SIZE(INTEGER) OF INTEGER
      END;
      
      Item2 = POINTER TO RECORD
         x: ARRAY r2Size DIV SIZE(INTEGER) OF INTEGER
      END;
      
      Item3 = POINTER TO RECORD
         x: ARRAY r3Size DIV SIZE(INTEGER) OF INTEGER
      END;

   VAR finCnt, maxAllocated: INTEGER;

   PROCEDURE (i: Item) FINALIZE;
   BEGIN
      i.p1 := NIL; i.p2 := NIL; i.p3 := NIL;
      i.a1 := NIL; i.a2 := NIL; i.a3 := NIL;
      INC(finCnt)
   END FINALIZE;

   PROCEDURE NewItem (): Item;
      VAR   res: Item;
   BEGIN
      NEW(res);
      NEW(res.p1);
      NEW(res.p2);
      NEW(res.p3);
      NEW(res.a1, a1Size DIV SIZE(INTEGER));
      NEW(res.a2, a2Size DIV SIZE(INTEGER));
      NEW(res.a3, a3Size DIV SIZE(INTEGER));
      RETURN res
   END NewItem;

   PROCEDURE MakeList (n: INTEGER; OUT first: Item);
      VAR   head, last: Item; m: INTEGER;
   BEGIN
      NEW(head); last := head;
      WHILE 0 < n DO
         last.next := NewItem(); last := last.next;
         DEC(n)
      END;
      first := head.next;
      m := Kernel.Allocated(); IF m > maxAllocated THEN maxAllocated := m END
   END MakeList;

   PROCEDURE ShowStatus;
   BEGIN
      Log.String("finCnt = "); Log.Int(finCnt); Log.Tab;
      Log.String("Kernel.Allocated() = "); Log.Int(Kernel.Allocated() DIV 1024); Log.String(" kB, ");
      Log.String("maxAllocated = "); Log.Int(maxAllocated DIV 1024);
      Log.String("kB        ");
      Log.Ln
   END ShowStatus;

   PROCEDURE Do (n: INTEGER);
      VAR   list: Item; i: INTEGER;
   BEGIN
      ASSERT(0 < n, 20);
      i := 0;
      LOOP IF i < n THEN
         MakeList(i, list); INC(i)
      ELSIF i < 2 * n THEN
         MakeList(2*n - i, list); INC(i)
      ELSIF i = 2 * n THEN
         ShowStatus;
         i := 0
      ELSE EXIT END END
   END Do;

   PROCEDURE Start;
   BEGIN
      Log.String("Ctrl+C to stop"); Log.Ln;
      Do(25)
   END Start;

BEGIN
   Start
END TestKernel_2.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 03 Август, 2023 02:32 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
спасибо, мне тоже пригодится. ;-)
с резервированием двух страниц-охранников падать не должно ни при каких n (пока памяти хватает).

про винду, кстати, я не в курсе, там может упасть — по той же причине пересечения опасного места. я толком не разбирался.

вообще, рекомендую аннигилировать режим монокластера в принципе, и переделать виндовый аллокатор по мотивам линуксового, через `VirtualAlloc()`. я у себя ещё кэш кластеров сделал: свободные кластеры живут в нём некоторое время (3-5 сборок), и только потом возвращаются системе.

также если надо памяти больше, чем размер кластера (у меня кластеры в 4 мб), то такой кластер не используется для выделения обычных объектов потом. идея в том, что это может быть огромный буфер, и если в нём выделят маленький объект — кластер зависнет выделеным навсегда. так можно у системы всю память выжрать, которая реально не используется.

ещё я планирую потом сделать lazy sweep. сейчас GC сразу свипает все кластеры — а можно это делать только по нужде, и маленькими шагами. тогда при большом количестве объектов выделение станет чуть-чуть медленней (но не шибко заметно), зато паузы GC уменьшатся. то есть, GC просканирует и отметит все объекты, но не будет ничего освобождать сразу, а только при следующем выделении, и закончит как только освободит блок достаточного размера. то есть, мы равномерно размажем время на sweep, зато собственно вызов коллектора будет немного быстрее.

правда, это потребует небольших изменений в маркере и сборщике: бит «отмечено» больше нельзя будет хранить в type tag, так что придётся его переместить куда-нибудь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 03 Август, 2023 12:34 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
arisu, спасибо!

https://github.com/bbcb/bbcp/commit/57f15fcf5f092ba44225d33712c2be4731cf3a6a


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Четверг, 03 Август, 2023 12:46 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
you're welcome, как говорится. я так понимаю, ваши тесты теперь нормально отработали? я у себя гонял — у меня до трёх гб спокойно выделяло. задолбался в итоге ждать, пока окончит (смотрел по htop, забавно прыгало вверх-вниз). правда, я не показатель: у меня адреса типа SYSTEM.ADDRESS (в mainline такого нет), беззнаковые.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Пятница, 04 Август, 2023 10:32 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3778
Пакет в Debian репозитории обновил.

Этот тест оказывается уже добавили в подситему Check. Модуль CheckKernel2.

Проверил ещё на OpenBSD и FreeBSD — работает исправление корректно.

Заодно починил в OpenBSD и FreeBSD переустановку сигналов для буфера обмена.

Внёс также (мы обсуждали в чате), чтобы для новичков поиск по справке F1 был без учёта регистра, а то не могут найти какие-то полезные вещи, так как галочка Ignore case не совсем очевидна.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 38


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB