Когда CLREX действительно необходим на ARM Cortex M7? - PullRequest
0 голосов
/ 03 июля 2018

Я нашел в сети несколько мест, в которых говорится, что CLREX «должен» вызываться всякий раз, когда вводится подпрограмма прерывания, чего я не понимаю. Документы для CLREX состояния (добавлена ​​нумерация для удобства):

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

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

(3) Определяется реализацией, очищает ли CLREX также глобальную запись исполняющего процессора о том, что адрес получил запрос на эксклюзивный доступ.

Я здесь ничего не понимаю.

У меня сложилось впечатление, что для написания чего-то вроде примера в документах было достаточно, чтобы гарантировать атомарность:

    MOV r1, #0x1                ; load the ‘lock taken’ value
try:                                                       <---\
    LDREX r0, [LockAddr]        ; load the lock value          |
    CMP r0, #0                  ; is the lock free?            |
    STREXEQ r0, r1, [LockAddr]  ; try and claim the lock       |
    CMPEQ r0, #0                ; did this succeed?            |
    BNE try                     ; no - try again   ------------/
    ....                        ; yes - we have the lock
  1. Почему «локальная запись» должна быть очищена? Я думал, что LDREX / STREX достаточно, чтобы гарантировать атомарный доступ к адресу от нескольких прерываний? То есть GCC для ARM компилирует все атомарные функции C11, используя LDREX / STREX, и я не вижу, чтобы CLREX вызывался где-либо еще.

  2. К какому «требованию для фиктивного магазина» относится второй абзац?

  3. В чем разница между global record и local record? Нужна ли глобальная запись для многоядерных сценариев?

Ответы [ 2 ]

0 голосов
/ 21 января 2019

На самом деле CLREX не , необходимый для исключений / прерываний на M7, он, по-видимому, включен только по соображениям совместимости. Из документации (версия c) :

CLREX обеспечивает совместимость с другими процессорами ARM Cortex, которые имеют заставить сбой магазина исключительным, если происходит исключение между инструкцией эксклюзивной загрузки и соответствующим магазином эксклюзивной инструкция в операции синхронизации. В процессорах Cortex-M, локальный монитор монопольного доступа очищается автоматически граница исключения, поэтому обработчики исключений, использующие CLREX, являются необязательными.

Итак, поскольку процессоры Cortex-M очищают локальный флаг монопольного доступа при исключении / прерывании входа / выхода, это сводит на нет большинство (все?) Вариантов использования для CLREX.

Что касается вашего третьего вопроса, то, как уже упоминали другие, вы правы, считая, что глобальный рекорд используется в многоядерных сценариях. Могут все еще быть случаи использования для CLREX на многоядерных процессорах в зависимости от эффектов, определенных реализацией для локальных / глобальных флагов.

Я могу понять, почему в этом возникает путаница, поскольку первоначальная версия документации M7 не включает эти предложения (не говоря уже о различных других версиях более общей документации на веб-сайте ARM). Даже сейчас я не могу даже дать ссылку на последнюю редакцию. На странице отображается «Версия a» по умолчанию, и вам необходимо вручную изменить версию с помощью выпадающего списка (надеюсь, это изменится в будущем).

Обновление

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

Процессор удаляет свой эксклюзивный тег доступа, если:

  • Выполняет инструкцию CLREX.

  • Выполняет инструкцию STREX, независимо от того, успешно ли выполнена запись.

  • Исключение. Это означает, что процессор может разрешать конфликты семафоров между различными потоками.

В многопроцессорной реализации:

  • Выполнение инструкции CLREX удаляет только локальный тег эксклюзивного доступа для процессора.

  • Выполнение инструкции STREX или исключение удаляет локальные теги эксклюзивного доступа для процессора.

  • Выполнение инструкции STREX в области разделяемой памяти также может удалить глобальные теги эксклюзивного доступа для процессора в система.

0 голосов
/ 04 июля 2018

Принимая (и перефразируя) ваши три вопроса отдельно:

1. Зачем очищать запись доступа?

Когда применяется строгое вложение кода, например, когда вы работаете с прерываниями, CLREX обычно не требуется. Однако бывают случаи, когда это важно. Представьте, что вы пишете переключатель контекста для вытесняющего ядра операционной системы, который может асинхронно приостанавливать запущенную задачу и возобновлять другую. Теперь рассмотрим следующую патологическую ситуацию, включающую две задачи одинакового приоритета (A и B), манипулирующие одним и тем же общим ресурсом с использованием LDREX и STREX:

Task A      Task B
  ...
 LDREX
-------------------- context switch
             LDREX
             STREX   (succeeds)
              ...
             LDREX
-------------------- context switch
 STREX               (succeeds, and should not)
  ...

Поэтому, чтобы избежать этого, переключатель контекста должен выдать CLREX.

2. Какого «требования к фиктивному магазину» избегают?

Если бы не было инструкции CLREX, то было бы необходимо использовать STREX, чтобы освободить флаг монопольного доступа, который включает транзакцию памяти и, следовательно, медленнее, чем нужно, если все, что вы хотите сделать, это очистить флаг.

3. Является ли «глобальный рекорд» для многоядерных сценариев?

Да, если вы используете одноядерный компьютер, есть только одна запись, потому что есть только один процессор.

...