LINUX.ORG.RU

Атомарные операции в ARM Cortex-M4

 


0

2

В документации сказано, что STREX возвращает единицу, и не трогает память по заданному адресу, если видит, что другой поток или процесс выполнил обращение к памяти в промежутке между LDREX и STREX. А по каким признакам определяется жизнедеятельность другого процесса/потока? Как ядро определяет, что память трогал именно другой процесс/поток?

А по каким признакам определяется жизнедеятельность другого процесса/потока?

Там же по твоей ссылке есть правильный пример использования

    MOV     R1, #0x1            ; Initialize the ‘lock taken’ value
try
    LDREX   R0, [LockAddr]      ; Load the lock value
    CMP     R0, #0              ; Is the lock free?
    ITT     EQ                  ; IT instruction for STREXEQ and CMPEQ
    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.

запись в этот регион памяти после блокировки невозможна - не важно сколько процессоров/потоков/процессов, другой процесс/поток просто будет курить бамбук в ожидании готовности

BNE try ; No - try again

anonymous
()
Ответ на: комментарий от anonymous

Охренеть! Там блокировки на уровне ядра!!!

Вах, сколько нам открытий чудных.. Это же так упрощает создание операционной системы!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от one_more_hokum

второе

// я с ассемблером плохо дружу, да и с программированием тоже не очень. ХЗ, как это правильно называть. Регистры вот эти временные.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

запись в этот регион памяти после блокировки невозможна - не важно сколько процессоров/потоков/процессов

Я и спрашиваю, по каким признакам ядро определяет, что память трогает другой поток/процесс? Какие регистры надо пнуть? Или флаги? Или стек сменить?

one_more_hokum ★★★
() автор топика

А где документацию нормальную взять почитать? А то ты совсем хреновую ссылку дал: там требуют регистрации.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

там требуют регистрации

Ты про ARM-ский сайт? Так там, вроде, для чтения документации регистрация не нужна. У меня, по крайней мере, не спрашивал.

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от one_more_hokum

Я еще не писал. Но мне нужна только многопоточность на M4, чтобы отфутболивать левые сетевые запросы. Ну и просто многопоточность иной раз нужна.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

запись в этот регион памяти после блокировки невозможна

A Store-Exclusive instruction
Used to attempt to write to the same memory location, returning a status bit to a register. If this bit is:
0
It indicates that the thread or process gained exclusive access to the memory, and the write succeeds.
1
It indicates that the thread or process did not gain exclusive access to the memory, and no write was performed.

Как я понял из вот этого, запись другим потоком/процессом возможна, но при этом упадёт какой-то флаг эксклюзивного доступа, и это можно будет отследить программно.

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от Eddy_Em

мне нужна только многопоточность

Вытесняющая, или кооператив? А таймеры всякие, примитивы синхронизации? Тоже, ведь, нужные штуки.

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Похоже, памяти нужно в 2 раза больше, чтобы еще и семафоры на каждую ячейку хранить. или я неправильно почитал

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от one_more_hokum

Простая многопоточность с приоритетами. Что-нибудь простое по синхронизации. Ну, таймеры, да.

А вообще, для элементарщины нужно немного. А то смотрел я эту freeRTOS — уж слишком перебор для меня. Ресурсов дофига жрет, а мне от нее нужно-то от силы 1% возможностей.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от one_more_hokum

Черт! Похоже, я когда-то запретил куки оттуда (разрешаю только нужным сайтам обычно), теперь не хочет...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

С ARM-ского сайта говорят, что

LDREX, LDREXB, and LDREXH load a word, byte, and halfword respectively from a memory address.
STREX, STREXB, and STREXH attempt to store a word, byte, and halfword respectively to a memory address. The address used in any Store-Exclusive instruction must be the same as the address in the most recently executed Load-exclusive instruction. The value stored by the Store-Exclusive instruction must also have the same data size as the value loaded by the preceding Load-exclusive instruction. This means software must always use a Load-exclusive instruction and a matching Store-Exclusive instruction to perform a synchronization operation, see Synchronization primitives.
If an Store-Exclusive instruction performs the store, it writes 0 to its destination register. If it does not perform the store, it writes 1 to its destination register. If the Store-Exclusive instruction writes 0 to the destination register, it is guaranteed that no other process in the system has accessed the memory location between the Load-exclusive and Store-Exclusive instructions.
For reasons of performance, keep the number of instructions between corresponding Load-Exclusive and Store-Exclusive instruction to a minimum.
Note:
The result of executing a Store-Exclusive instruction to an address that is different from that used in the preceding Load-Exclusive instruction is unpredictable.
Restrictions:
In these instructions:
do not use PC
do not use SP for Rd and Rt
for STREX, Rd must be different from both Rt and Rn
the value of offset must be a multiple of four in the range 0-1020.
Condition flags:
These instructions do not change the flags.

но какие действия приведут к опознаванию доступа к памяти из других потоков/процессов — не указано.

one_more_hokum ★★★
() автор топика

См. LL/SC (Linked Load/Store Conditional или Locked Load/Store Conditional) в википедии. Вкратце - используются сведения об инвалидации кэш-линий, исключения и пр. Т.е., даже запись/чтение другой ячейки памяти из той же нитки может привести к неудаче записи в STREX (он же - SC). Данные инструкции годны для реализации примитивов (типа мьютексов, семафоров и т.п.) на ассемблере, т.к. в сишном коде что угодно может привести к постоянной неудаче SC.

dmitry_vk ★★★
()
Ответ на: комментарий от dmitry_vk

Весело. Т.е., ненулевая вероятность сбросить флаг эксклюзивного доступа между LDREX и STREX из C-шного кода есть? И STREX будет крутиться в бесконечном цикле, хоть никакие другие потоки и близко к памяти той не подступались?

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от dmitry_vk

Или это только про саму реализацию синхропримитивов?

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от dmitry_vk

Вкратце - используются сведения об инвалидации кэш-линий

вкратце - ты гонишь

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0321a/BIHEADII...

System level cache

The Cortex-M0, Cortex-M0+, Cortex-M1, Cortex-M3, and Cortex-M4 processors do not have any internal cache memory. However, it is possible for a SoC design to integrate a system level cache. Note

A small caching component is present in the Cortex-M3 and Cortex-M4 processors to accelerate flash memory accesses during instruction fetches.

Весело. Т.е., ненулевая вероятность сбросить флаг эксклюзивного доступа между LDREX и STREX из C-шного кода есть?

нет и ЯП тут вообще нипричем

If an Store-Exclusive instruction performs the store, it writes 0 to its destination register. If it does not perform the store, it writes 1 to its destination register. If the Store-Exclusive instruction writes 0 to the destination register, it is guaranteed that no other process in the system has accessed the memory location between the Load-exclusive and Store-Exclusive instructions.

anonymous
()
Ответ на: комментарий от anonymous

If an Store-Exclusive instruction performs the store, it writes 0 to its destination register. If it does not perform the store, it writes 1 to its destination register. If the Store-Exclusive instruction writes 0 to the destination register, it is guaranteed that no other process in the system has accessed the memory location between the Load-exclusive and Store-Exclusive instructions.

Что в переводе значит: «Если инструкция Store-Exclusive выгрузила данные, она запишет 0 в регистр результата. Если выгрузка данных не произведена, в регистр результата запишется 1. В случае нуля в регистре результата гарантируется, что ни один прочий процесс/поток в системе не производил доступ к участку памяти, в который производится выгрузка, между выполнением инструкций Load-exclusive и Store-Exclusive».

Это я к тому, что читать тоже умею, но вот как именно ядро опознаёт факт доступа другого процесса/потока к участку памяти, на который сказали Load-exclusive — я не нашёл.

one_more_hokum ★★★
() автор топика
Последнее исправление: one_more_hokum (всего исправлений: 1)
Ответ на: комментарий от one_more_hokum

но вот как именно ядро опознаёт факт доступа другого процесса/потока к участку памяти, на который сказали Load-exclusive — я не нашёл.

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

anonymous
()
Ответ на: комментарий от anonymous

какая тебе лично разница - как это реализовано аппаратно?

Такая, что по большому счёту разница между потоками в BareMetal-операционке исчезающе мала. Подменил регистры, переуказал стек — вот тебе другой поток (ну, сильно топорно, конечно, но основная идея). А если само ядро контроллера знать про потоки ничего не знает — то не исключена ситуация, когда путём каких-нить манипуляций после LDREX я сброшу флаг эксклюзивного доступа, и ядро будет думать, что STREX, который идёт после этих манипуляций — уже от другого потока. И будет он болтаться в бесконечном ожидании, хотя на самом деле никто посторонний память не трогал.

Что-то я недопонимаю пока. Сильно недопонимаю.

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от one_more_hokum

Подменил регистры, переуказал стек — вот тебе другой поток

ты реально не понимаешь что программист должен проверять блокировку ? или ты из тех кто на красный свет ломится и помочь может только удар дубиной по башке ?

anonymous
()
Ответ на: комментарий от anonymous

Ты читать вообще умеешь? А осмысливать прочитанное?

ты реально не понимаешь что программист должен проверять блокировку?

Подменил регистры, переуказал стек — вот тебе другой поток

Диспетчер задач, что ли, должен за каждой LDREX следить? Как ты это вообще представляешь?

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от one_more_hokum

Диспетчер задач, что ли, должен за каждой LDREX следить?

идиот - это вход в критическую секцию - какая разница, какой поток в нее входит ?? не смог получить доступ - bne в цикле пока не освобит тот кто выставил блокировку. Ты блять светофор никогда не видел ? он тебе гарантирует что если у тебя зеленый - у другого красный, а идти или стоять - тебе решать.

anonymous
()
Ответ на: комментарий от one_more_hokum

Диспетчер задач, что ли, должен за каждой LDREX следить? Как ты это вообще представляешь?

какой еще диспетчер задач? если во время выполнения LDREX-STREX прилетело прерывание и обработчик или нить на которую переключился планировщик попытаются постучится по тому же адресу то получать банан. вот и вся «атомарность».

exception13 ★★★★★
()
Ответ на: комментарий от one_more_hokum

Это я к тому, что читать тоже умею, но вот как именно ядро опознаёт факт доступа другого процесса/потока к участку памяти, на который сказали Load-exclusive — я не нашёл.

для процессора нет потоков или процессов. есть только поток команд.

пример «валидного» потока LDREX SOMEOPS STREX

пример «не валидного» потока LDREX LDREX SOMEOPS STREX

exception13 ★★★★★
()
Ответ на: комментарий от one_more_hokum

короче считай LDREX/STREX этакими «аппаратными операторными скобками» если процессор встречает открывающуюся скобку в то время как предыдущая не закрыта или закрытую в то время как уже была закрыта то соответственно считает что где то что то пересеклось.

exception13 ★★★★★
()
Ответ на: комментарий от exception13

для процессора нет потоков или процессов. есть только поток команд

Это знаю, потому и вызывает непонимание

пример «не валидного» потока LDREX LDREX SOMEOPS STREX

Если между LDREX и STREX случится переключение контекста, и сброс флага эксклюзивности доступа — настанут вилы?

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от one_more_hokum

Если между LDREX и STREX случится переключение контекста, и сброс флага эксклюзивности доступа

тебе гарантируется если strex вернул 0 - никто кроме тебя доступ не имел, только если такой же ебанат как ты без проверки сбросит блокировку, нормальный поток зависнет на bne только в другом или в том же месте кода. Да - про взаимную блокировку погугли, что такое дидлок, подумай - когда перерывания надо отключать.

anonymous
()
Ответ на: комментарий от anonymous

такой же не матерись как ты без проверки сбросит блокировку, нормальный поток зависнет на bne

То есть, если реализуется следующий сценарий:

SwitchToThread1 -> LDREX -> SwitchToThread2 -> LDREX SOMEOPS trySTREX -> SwitchToThread1 -> trySTREX

то получится deadlock? Между LDREX и trySTREX одного потока нужно запрещать прерывания? Какой тогда смысл в этих инструкциях?

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

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от one_more_hokum

Чем эти колбаски со стрелками рисовать - погугли как этим другие пользуются.

anonymous
()

Подведем итог.

1. ССЗБ если между LD и ST много действий ()не более 128 байт инструкций).

2. Это всего навсего аппаратная поддержка «мониторов» для синхронизации, если ты хочеш софтварную моддержку нитей - пиши её другим способом.

3. Документацию ты читал не внимательно, т.к. на все твои вопросы там были ответы: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/CJAGCFAF...

А именно: каким же лешим реализуется монитор в рамках ядра процессора.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.