Перейти к содержанию
    

Проверил union. Не работает.

Заодно проверил, достаточно ли объявить как volatile только First, но не Last. Тоже недостаточно:

ER_IROM1:0000202A                 STRH            R7, [R0,#8]
ER_IROM1:0000202C                 STR             R5, [R0,#0xC]
ER_IROM1:0000202E                 STRB            R2, [R0,#0x10]
ER_IROM1:00002030                 STRD.W          R2, R6, [R0]
ER_IROM1:00002034                 LDR             R1, [R4,#4]
ER_IROM1:00002036                 LDR             R3, [R4,#8]
ER_IROM1:00002038                 CMP             R1, R0
ER_IROM1:0000203A                 STR             R0, [R3]
ER_IROM1:0000203C                 ADD.W           R3, R8, #1
ER_IROM1:00002040                 STR             R0, [R4,#8]
ER_IROM1:00002042                 STRB.W          R3, [R4,#0x40]
ER_IROM1:00002046                 BNE             loc_20A2

Загрузка First и Last выполняется двумя отдельными командами (2034 и 2036), однако выборка First опять произошла до записи по Last.

1 час назад, amaora сказал:

Так значит типы разные все таки бывают при работе с First и Last?

Фактически -- да. First всегда указывает на первый элемент очереди (FIFO_LNK) или содержит нуль, если очередь пуста. А вот Last указывает либо на последний элемент очереди (FIFO_LNK), либо на поле First самого заголовка (или, если угодно, на сам заголовок -- FIFO_HDR).

1 час назад, jcxz сказал:

Странно, а мы видим иное: запись по адресу в Last, как видим, происходит непосредственно после загрузки First.

Эм... Почему? Выборка из Last идёт по адресу 2080 (самая первая LDR), запись по Last -- в 208E, а выборка First -- в 2090. В 2092 идёт запись в Last.

1 час назад, Arlleex сказал:

Я, так понял, здесь классическая "грабля" с оптимизацией при strict aliasing, которую каждая тематическая статья приводит в пример

Похоже на то. В общем, не глюк компилятора, а оптимизация. Правда, остаётся непонятным, почему именно он выкидывал кусок кода в моём самом первом сообщении этой темы (в операции new): вроде б не должен столь своевольно обращаться с кодом, тем более, что в delete он уже не умничал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, SII сказал:

Правда, остаётся непонятным, почему именно он выкидывал кусок кода в моём самом первом сообщении этой темы (в операции new): вроде б не должен столь своевольно обращаться с кодом, тем более, что в delete он уже не умничал.

Все вполне может быть объяснено тем же самым механизмом строгого alias. Компилятор, видя строчку

reinterpret_cast<puint32>(Ptr)

сразу отмечает undefined behavior и, соответственно, генерирует то, что ему вздумается.

Компилятор считает, что полученный uint32_t * не может указывать туда же, куда указывает Ptr. А раз не указывает, а от функции требуется вернуть Ptr, то вся работа с uint32_t * выкидывается за ненадобностью, ибо никакие манипуляции с uint32_t * (тем, куда этот указатель смотрит) теоретически (так предполагает компилятор при strict aliasing) не изменят Ptr.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Arlleex сказал:

Все вполне может быть объяснено тем же самым механизмом строгого alias

А почему тогда в delete не выбрасывает? Действия-то принципиально одинаковые выполняются...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...