netch: (Default)
[personal profile] netch
(UPDATE log: с аргументом делегата - меня научили военным хитростям)

Нормальные люди, как известно, начинать считают с единицы, программисты - с нуля. BSD'шники переплюнули программистов: у них счёт начинается с минус единицы.


Первый пример: чтобы во FreeBSD в /etc/rc.conf задать адрес на сетевом интерфейсе, надо определить переменную ifconfig_ZZZ, где ZZZ - имя интерфейса. Если одного адреса не хватает... заводится ifconfig_ZZZ_alias0. Нормальный человек назвал бы её примерно как ifconfig_ZZZ_address2, программист - помня, что основной адрес вроде как нулевой - ifconfig_ZZZ_alias1. Видимо, радикализма программистов оказалось недостаточно.

Второй пример: логфайлы. Если /var/log/messages "проротейчен" (сдвинут в сторону и на его месте открыт новый) - он становится... да, уже многие догадались (если не знали уже) - /var/log/messages.0. (Ну или /var/log/messages.0.gz, если он ещё и сжимается.) Почему 0, почему не 1? Видно, великая тайна есть в развитии BSD систем, которую не понять даже такому привыкшему уже к FreeBSD старому извращенцу, как я.

К чему это я вспомнил? Ну да, читая книгу по C# обнаружил, что старый добрый printf авторов оного не устроил (ну ещё бы, великий принцип NIH - "not invented here" - руководит чуть ли не всей деятельностью конструкторской и программной разработки). Вместо старых добрых %<n>.<m><f> (например, %d - целое число со знаком, или %12.3f - вещественное число в формате фиксированной точки с 12 позициями всего и 3 после точки) - введено нечто принципиально новое: {номер_аргумента,ширина:формат}. Сразу вспомнился gettext: его выгибоны для перестановки параметров получили естественное подкрепление, теперь локализовать выводимые сообщения в System.String.Format() значительно легче. Но первый аргумент после форматной строки... имеет номер 0! Видимо, Microsoft вместе с сетевым стеком FreeBSD подхватило вирус "минус единицы", пронумеровав ею саму форматную строку.

То что совместимость с семейством printf потеряли - об этом можно и не вспоминать. Вперёд, заре навстречу, товарищи в борьбе... Да, аналогов подходов funopen() и fopencookie() в System.IO нету, не по чину такое реализовывать. Хорошо, что хоть не мешают это делать построением своих классов, в отличие от проприетарных stdio.

С тредами мы наблюдаем другой вид чудес. Для запуска нового треда в C# надо, кроме прочих шаманских действий, занести свой метод в делегат следующего вида:

public delegate void ThreadStart();

Сравнивая с другими реализациями (например, pthreads) видим отсутствие аргумента на входе:

typedef void *(*pthread_startroutine_t)(void *);

"Гады! Редиски! Куда аргумент дели?" Не надо думать, что этот плач бессмысленный; если бы передавался параметр типа object, можно было бы через него передать любую информацию, точно так же как через void* в plain C. А что остаётся - глобальные переменные? А если у нас два или больше, например, идентичных по схеме построения worker pool'а, но с разными множествами рабочих нитей (абсолютно нормальный дизайн, однако)? Сериализовать старт новых нитей? А ведь иного и не остаётся. Тут уже подсказали, что есть типа секретный метод (Шилдт про него молчал как партизан, надо было тщательно проштудировать примеры кода чтобы понять трюк), так что исправляюсь - не всё так безнадёжно. Но - 1) почему это не описывают явно и открыто? 2) почему так через одно место? На дворе всё-таки даже для первой версии был 2000-й год, а не 1970-й.

Это напомнило мне метод старта новых процессоров в Intel SMP (подробности на developer.intel.com в мануалах к Pentium, для более поздних процессоров эта документация не дублировалось). Передать что-то процессору в том IPI (inter-process interrupt), который его запускает, например, адрес точки старта и значение хотя бы одного регистра? Да боже упаси, от этого корона свалится! Поэтому:
- старт процессоров, ясен пень, сериализуется - пока один не отрапортовал что тангаж, крен и рысканье в норме, следующие на взлёт не отправляются.
- пишется системная процедурка, которая вылавливает из памяти из глобальной переменной, кого же стартуем, и начинает соответствующую отработку.
- в область данных BIOS пишется специальное указание "после проверки процессора переходить на заданный адрес" (через него в 80286, в частности, делался переход в real mode). Что будет, если в этот момент придёт reset - можно только догадываться, скорее всего, машину придётся дёргать только по питанию.
- наконец, толкаем IPI. Процессор выйдя из спячки уходит выполнять код по стандартным FFFF:0000 в real mode. Прочитав заветный приказ по 0x0470-0x0473, уходит на процедуру ОС. Стартовав, та снимает все эти навороты чтобы reset сработал:)

Стра-ашно? Вот-вот, теперь берём передачу в делегат вместе с методом объекта - объект и уходим от этого ужаса. Довольные тем, что перехитрили всех:)

Впрочем, first-class functions с возможностью конструирования их на ходу от этого всё равно не появятся. Какое-то подобие замыканий (и опять через двуединую сущность с вертикальной улыбкой!) обещают во второй версии, да когда же она будет достаточно распространена...

Впрочем, мне это всё пока что теория - ни одной живой строчки на нём я не написал и, видимо, не скоро напишу. Может, у реальных писателей на оном, стаж которых к данному моменту достиг уже 10 лет непрерывного применения в сложных условиях борьбы с тараканами оконного интерфейса и оптимизациями языка 1С, мои плачи вызовут только ироническую ухмылку - не тем, мол, занимаешься. Ладно, посмотрим.

А вообще, впечатление от оной продукции, мягко говоря, грустное. Что стоило, например, убрать вечную проблему "к какому if относится данный else?" и сделать нормальный else-if? Неужели сохранение совместимости с дизайном 35-летней давности (старше конструкции моего пердящего драндулета) стоит того, чтобы распространять грабельное поле ещё на ближайшие 10-20 лет?

Date: 2005-09-03 09:28 pm (UTC)
From: [identity profile] dinozavrik.livejournal.com
> И что тебе дадут те NX-биты?

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

Profile

netch: (Default)
netch

December 2023

S M T W T F S
     12
3456789
10111213141516
171819 20212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 3rd, 2026 03:16 pm
Powered by Dreamwidth Studios