реклама на сайте
подробности

 
 
> Зачем нужен барьер памяти (DMB) перед LDREX
bublik
сообщение Feb 15 2015, 09:21
Сообщение #1





Группа: Новичок
Сообщений: 9
Регистрация: 6-10-11
Пользователь №: 67 570



Зачем нужен барьер памяти (DMB) перед LDREX

Здравствуйте, к сожалению не смог найти ответ на вопрос: зачем нужен барьер памяти (DMB) перед LDREX.

Суть вопроса:

В архитектурах ARMv6 и ARMv7 вместо операции SWP нужно использовать пару: LDREX/STREX.

Вот так например будет выглядеть атомарная операция сложения:

Код
void atomic_add(int *obj; int val)

.try:
    Ldrex    r2,  [r0]                
    add       r2,  r2, r1                                      
    strex     r3,  r2, [r0]                                    
    teq        r3,  #0                                          
    bne     .try                                                                            
    bx      lr


Все прекрасно работает и т.п.

Но это если функция атомарного сложения у нас void. Если же мы сделаем ее, чтобы она возвращала результат:

Код
int atomic_add(int *obj; int val)
.try:
    Ldrex    r2,  [r0]                            
    mov      r12, r2                                          
    add       r2,  r2, r1                                      
    strex     r3,  r2, [r0]                                    
    teq        r3,  #0                                          
    bne     .try      
    DMB                           //барьер                                
    mov     r0,  r12                                        
    bx      lr


Добавляется барьер (DMB) – это сделано для того, что если мы будем использовать данную функцию для реализации примитива синхронизации, мы при входе в критическую секцию знали (была дана гарантия), что те данные которые мы защищаем (работаем в критической секции) были в валидном состоянии (все операции по сохранению были завершены) подробнее в Barrier_Litmus_Tests_and_Cookbook_A08.pdf (http://infocenter.arm.com/help/topic/com.arm.doc.genc007826/Barrier_Litmus_Tests_and_Cookbook_A08.pdf)

Но мне не понятно, зачем gcc 4.9.2 для атомарных операций (С11) типа atomic_fetch_add
Вставляет dmb, до ldrex:

Код
int atomic_fetch_add(int *obj; int val)
     DMB    SY                     // я не понимаю зачем нужен этот барьер
.try:
    Ldrex    r2,  [r0]                            
    mov      r12, r2                                          
    add       r2,  r2, r1                                      
    strex     r3,  r2, [r0]                                    
    teq        r3,  #0                                          
    bne     .try      
    DMB    SY                    //барьер                                
    mov     r0,  r12                                        
    bx      lr


Аналогично сделано для атомарных операций в ядре Linux: /arch/arm/include/asm/atomic.h

Нашел коммит, который добавляет все это дело: https://git.kernel.org/cgit/linux/kernel/gi...0e59aa68af3b43a

Автор говорит, что это требуется для операций, которые возвращают результат (с нижним DMB – понятно) но верхний ?

Зачем нужный DMB до LDREX ?

Спасибо.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
kimstik
сообщение Mar 22 2017, 13:55
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 46
Регистрация: 4-02-05
Из: Москва
Пользователь №: 2 430



А по мне это похоже на обход эрраты ARM 782772
Там предлагают DMB перед LDREX ставить
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th August 2025 - 08:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01376 секунд с 7
ELECTRONIX ©2004-2016