Pull to refresh
2
0
Send message
Я занимался Люстрой в 2004-2009, потом другой системой, для exascale.
Из упущенного: DAOS, http://storageconference.us/2015/Presentations/Gorda.pdf.
«Intel Infiniband»… Intel, конечно, всему голова, но стандарт просто Infiniband. :-)
Да, при прочих равных лучше в каноническом порядке отпускать локи. Меня просто смутила формулировка в статье. Статьи отличные, кстати. Спасибо.
Вы можете описать ситуацию, когда неправильный порядок *разблокировки*, т.е. отпускания мьютексов, приводит к проблемам? Ситуации, когда { unlock(A); unlock(B); } корректно, а { unlock(B); unlock(A); } ведет к deadlock-y?
> и, наконец, разблокируем все мьютексы в обратном порядке — справа налево. Не забываем, что основная причина deadlock – несоблюдение порядка блокировки/разблокировки нескольких мьютексов.

Разве порядок разблокировки может быть причиной deadlock? «Неправильная» разблокировка (слева направо, в данном случае) может привести к образованию конвоя или thundering herd, но никак не к deadlock-у.
> Вы, похоже, пытаетесь выкрутиться из ситуации, придираясь к слову «разыменование».
В моих комментариях, которые вам необходимо перечитать, с самого начала и неоднократно было указано, что я понимаю «разыменование», как применение unary operator *. Каким образом вы его понимаете — до сих пор непонятно.

> Но это не так важно, ибо соответствующий раздел — «informative», а не «normative».
Есть другие примеры undefined behaviour, которые авторы решили не включать в этот список, или это удивительное исключение?
> Речь в данном разговоре идет о формальной легальности конструкции (size_t)&(((s *)0)-›m)
Очень жаль, что вы все время об этом разговаривали, потому что я, как как и было написано в моем первом сообщении, говорю о том, что в этой конструкции нет разыменования (т.е. применения unary *), вне зависимости от того, легальна ли вся конструкция.

Например (приходится повторить), в конструкции A[B] есть разыменование, потому что стандарт явно определяет ее как (*(A+B)). Для конструкции A->B такого сведения нет. Вы, кажется, пользуетесь каким-то своим неформальным пониманием разыменования, не определив его явно.

> И этк конструкция — нелегальна, ибо содержит применение оператора -> к указателю, не являющемуся указателем на объект.
Вы можете процитировать соответствующий пункт из списка undefined behaviours в конце стандарта?
> Наоборот 6.5.3.2/1 это запрещает.
Где конкретно? Там явно написано «The operand of the unary & operator shall be [...] unary * operator» и никаких ограничений на аргумент * нет, т.е. явно разрешается &(*(X)) для произвольного X.

Что значит «предотвращает запрещенное разыменование»? Стандарт просто отмечает, примечанием, что результат &(*0) должен быть 0, там ничего не говорится ни про какую «аннигиляцию».

> Оператор -> — это разыменование указателя.
Смешались в кучу кони, люди. :-)

С точки зрения стандарта, -> это не разыменование, семантика -> описана специальным образом (6.5.2.3), но стандарт гарантирует, что при некоторых условиях (X)->Y эквивалентно (*(X)).Y (примечание 69).

С неформальной точки зрения, offsetof(A, B) это просто константа компиляции, и никакого разыменования, т.е. обращения к памяти, ее вычисление не требует.

> На такой платформе такая реализация offsetof работать не будет.
С этим никто не спорит, у offset() есть и гораздо менее экзотические проблемы. И также понятно, что традиционная реализация вызывает undefined behaviour. Но вовсе не из-за отсутствующего там разыменования, а потому, что семантика A->B стандартом не сводится к арифметике над указателями (в отличие от семантики A[B]).

Обычный offsetof() может привести к undefined behaviour, когда применяется как offsetof(struct foo, array[n]), где n — больше числа задекларированных элементов в поле-массиве. Типичная ситуация: массив нулевой длины в конце структуры, фактически память под массив выделяется при аллокации.
Во-первых, применять адресную арифметику к null pointer стандартом C явно разрешено (см. C99, 6.5.3.2, особенно примечание 74, где явно указано, что даже разыменование нулевого указателя бывает законно). Во-вторых «разыменование null pointer» это применение операции разыменования (unary * operator) к нулевому указателю, а в макросе offsetof() такая операция просто-напросто отсутствует: этот макрос ничего не разыменовывает.
> А между тем еще в Турбо Паскале была возможность вкладывать одни функции в другие.
Как уточнение: вложенные функции были в Паскале с самого начала и, вообще, присутствуют почти во всех языках, происходящих от Алгола-60, C здесь как-раз исключение.

> Однако, это является неопределенным поведением по стандарту Си (из-за разыменования нуля)
offsetof() NULL не разыменовывает, он выполняет арифметические операции над NULL-pointer, что совершенно законно.

Да, он его изобрел и использовал в компиляторе Алгола-60.
> Этот механизм в чем-то похож на уровень привилегий х86.
Этот массив дескрипторов называется Dijkstra display: http://cs-exhibitions.uni-klu.ac.at/index.php?id=4&uid=9.
> Однако такая конфигурация обладает рядом свойств, которые сильно затрудняют работу с ней в случае, когда клиенты используют независимые виртуализированные кластера.

Вы не могли бы пояснить, какие проблемы у Люстры в такой конфигурации?
На отсканированных листочках «программирования в машинных кодах, без ассемблера» не видно, там обычный ассемблер.

Кроме того, Алгол-68 (на котором приведен пример) и Алгол-60 это совершенно разные языки.
В BNF нужно заменить "," на "','".
Лисп изначально основан на теории рекурсивных функций, а не на лямбда исчислении.
Почтальон звонит (дважды). :-)

Information

Rating
Does not participate
Registered
Activity