Поиск
Показаны результаты для тегов 'dmb ldrex'.
-
Зачем нужен барьер памяти (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 ? Спасибо.