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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Работа с переменными в прерывании и основном теле, жутко неудобно выходит
_Pasha
сообщение Oct 5 2015, 13:36
Сообщение #16


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Alexashka @ Oct 5 2015, 00:53) *
Поясните пожалуйста, что значит readonly если я как читаю указатель, так и пишу его (инкрементирую) wacko.gif
И что делает эта строчка
Код
while(res != *dsc) res = *dsc;
К сожалению не читал обсуждение темы, о которой Вы говорите, если есть ссылочка прошу направить в нужном направлении sm.gif

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

Сообщение отредактировал _Pasha - Oct 5 2015, 13:38
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Oct 6 2015, 07:29
Сообщение #17


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Цитата(jcxz @ Oct 5 2015, 15:58) *
Там где они модифицируются, можно делать только так, как я написал. А не напрямую глобальные.
Если Вы этого не поняли, значит не поняли ничего в моих функциях.

Да вроде понятно всЁ. Ну я например работаю непосредственно с глобальными и вроде все работает (блокирую прерывание непосредственно перед сравнением двух глобальных переменных).
С копированием получается наглядней в том смысле что имеем только 2 места где нужно ставить блокировку прерывания, и к локальной переменной можно обращаться сколько угодно раз. Я правильно понимаю идею?

Цитата(Сергей Борщ @ Oct 5 2015, 15:53) *
Все три известные мне компилятора для x51 (Кейл, Иар и SDCC) позволяли объявлять указатель на конкретный тип памяти. Такие указатели и меньше места занимают и работают без этого ветвления. Посмотрите документацию на свой компилятор, наверняка они там есть.

Проверил- и действительно: добавил спецификатор памяти в объявление указателя и всё лишнее в коде исчезло. Вот оно как оказывается, Михалыч (с) laughing.gif Спасибо за информацию, Сергей! a14.gif

Цитата(_Pasha @ Oct 5 2015, 16:36) *
Мы читаем указатель, но не запрещаем прерывания. Указатель считается валидным, если за два чтения подряд он не был изменен процессом более высокого приоритета. Это и есть неатомарное чтение. Быстро ли, медленно ли? Наверное, если это имеет значение - пора утяжелять прерывание.

Понял идею, но это ведь можно провернуть не только с указателем, но и с любой переменной?
Добавлено: попробовал Вашу функцию, вроде работает, только выдает предупреждение
Цитата
Pointer truncation
A spaced pointer has been assigned some constant value which exceeds the
range covered by the pointers memory space. For example:

char idata *p1 = 0x1234; /* result is 0x34 */
Go to the top of the page
 
+Quote Post
jcxz
сообщение Oct 6 2015, 08:10
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Alexashka @ Oct 6 2015, 13:29) *
Да вроде понятно всЁ. Ну я например работаю непосредственно с глобальными и вроде все работает (блокирую прерывание непосредственно перед сравнением двух глобальных переменных).
С копированием получается наглядней в том смысле что имеем только 2 места где нужно ставить блокировку прерывания, и к локальной переменной можно обращаться сколько угодно раз. Я правильно понимаю идею?

Не только в сравнении дело.
Я не понимаю что значит "заменить на глобальные". Если просто тупо подменить в моих функциях все использования локальных на соответствующие им глобальные - работать не будет.
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Oct 6 2015, 08:41
Сообщение #19


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Цитата(jcxz @ Oct 6 2015, 11:10) *
просто тупо подменить в моих функциях все использования локальных на соответствующие им глобальные - работать не будет.

Загадка rolleyes.gif...

В предположении, что read() не вызывается и rpos не модифицируется в прерывании:
Код
int read()
{
__disable_interrupt();
  if (rpos == wpos) return -1;
__enable_interrupt();
  if (--rpos < 0) rpos = sizeof(buf) - 1;
  return  buf[rpos];
}

Не будет работать??
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 6 2015, 10:49
Сообщение #20


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(jcxz @ Oct 5 2015, 07:12) *
Это то же самое, что просто запрет прерывания на время чтения *dsc. Никакого преимущества не даёт по сранению с обычным запретом прерываний.
По скорости может быть как медленнее так и быстрее запрета - в зависимости от CPU.

Преимущество - не надо городить критические секции.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 6 2015, 11:51
Сообщение #21


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Alexashka @ Oct 6 2015, 10:29) *
Добавлено: попробовал Вашу функцию, вроде работает, только выдает предупреждение

Ну я как бы тоже "из головы" писал, не с реального примера. У меня не случались неатомарные чтения по указателю. Мог и что-то упустить.
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Oct 6 2015, 16:36
Сообщение #22


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Цитата(_Pasha @ Oct 6 2015, 14:51) *
Ну я как бы тоже "из головы" писал, не с реального примера. У меня не случались неатомарные чтения по указателю. Мог и что-то упустить.

Да нет все ок, разобрался sm.gif
Заменил
Код
char *p  = nonatomic_ptr(&r_pos);

на
Код
char *p;
p = nonatomic_ptr(&r_pos);

и ашИпка ушла
Go to the top of the page
 
+Quote Post
jcxz
сообщение Oct 7 2015, 02:41
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(MrYuran @ Oct 6 2015, 16:49) *
Преимущество - не надо городить критические секции.

И что такого страшного в критических секциях????
Go to the top of the page
 
+Quote Post
Valentine Logino...
сообщение Oct 7 2015, 07:13
Сообщение #24


Частый гость
**

Группа: Участник
Сообщений: 78
Регистрация: 7-04-10
Из: Пушкино
Пользователь №: 56 462



Вариант с так называемым "nonatomic" по-русски называется костыль. Если есть проблемы с атомарным доступом к индексам кольцевого буфера - нужно задуматься о разделении доступа к самому буферу через флаг с атомарным доступом. Вы слабо описали задачу, т.к. совершенно непонятно где именно мешает атомарность.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 7 2015, 07:25
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Valentine Loginov @ Oct 7 2015, 10:13) *
нужно задуматься о разделении доступа к самому буферу через флаг с атомарным доступом.

Задумался...sm.gif получил замену атомарной работы с указателями на замену работы с атомарным флагом и добавление самого флага sm.gif sm.gif sm.gif
На самом деле атомарная работа с флагами может быть еще более гнусной вещью. У заметного количества контроллеров работа с модификацией памяти категорически не атомарная sad.gif.
И при попытке изменить флаг, который меняется и в прерывании наступает &*%&^*%


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Valentine Logino...
сообщение Oct 8 2015, 07:35
Сообщение #26


Частый гость
**

Группа: Участник
Сообщений: 78
Регистрация: 7-04-10
Из: Пушкино
Пользователь №: 56 462



Идея в том, что атомарный флаг делается тоже через критические секции, другое дело, что к нему обращается программа куда реже, чем к индексам буфера, за счет чего снижается количество критических секций.
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Oct 8 2015, 07:58
Сообщение #27


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Цитата(Valentine Loginov @ Oct 8 2015, 11:35) *
Идея в том, что атомарный флаг делается тоже через критические секции, другое дело, что к нему обращается программа куда реже, чем к индексам буфера, за счет чего снижается количество критических секций.

Не знаю может это тоже самое, но у меня была была идея такая: в основной программе работаем не с самими индексами буфера, а с их копиями, причем перед обращением к переменным-копиями устанавливаем спец.флаг занятости, потом сбрасываем его. В прерывании текущее значение индекса копируется в переменную-копию в том случае, если флаг занятости не установлен, если же он установлен -копирование не производится (оно произойдет при последующих заходах в прерывание). Есть однако вероятность (хоть и небольшая, но есть) что при каждом заходе в прерывание флаг занятости будет установлен и мы так и не сможем обновить наши копии индексов. Однако в этом случае проблема с атомарностью не возникает, т.е. критические секции вообще не нужны и нет задержки входа в прерывание.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Oct 8 2015, 09:09
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Alexashka @ Oct 8 2015, 13:58) *
Есть однако вероятность (хоть и небольшая, но есть) что при каждом заходе в прерывание флаг занятости будет установлен и мы так и не сможем обновить наши копии индексов. Однако в этом случае проблема с атомарностью не возникает, т.е. критические секции вообще не нужны и нет задержки входа в прерывание.

Есть вероятность, что Ваше ПО сейчас работает, а через 10 секунд - есть вероятность, что не работает. Сейчас работает, а если добавить ещё строчку в исходник - есть вероятность, что не заработает.
Вероятно наиболее вероятное место такому вероятному ПО - на помойке wink.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 8 2015, 09:13
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Valentine Loginov @ Oct 8 2015, 10:35) *
Идея в том, что атомарный флаг делается тоже через критические секции, другое дело, что к нему обращается программа куда реже...

Не бывает так, что какой-то флаг, который что-то вне прерывания прикрывает, используется реже, чем то, что он прикрывает.
Посему лишняя сущность в таких простых задачах. Если речь идет о множественных действиях каким-то перемеными, тогда да - экономнее один раз взвести-уронить, чем заниматься оформлением в критичекие секции каждой из переменных. Хотя и в таком случае нужно думать о простом расширении критической секции.

Ну а вообше не забываем о том, что кроме огульного запрещения всех прерываний запрещать в критической секции можно ТОЛЬКО конкретные источники прерываний с которыми может быть конфликт.



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 8 2015, 09:31
Сообщение #30


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Pasha @ Oct 4 2015, 14:27) *
Код
volatile char *r_pos, w_pos;
char * nonatomic_ptr(char ** dsc)
{
  char * res = *dsc;
  while(res != *dsc) res = *dsc;
  return res;
}

char *p  = nonatomic_ptr(&r_pos);

если оптимизатор выкидывает - dsc должен быть volatile, наверное

Читать и сравнивать целиком 2-байтовый указатель - неоптимально. Можно прочитать старший байт, затем младший, затем снова старший, и если он не изменился, значит, 2-байтовое число верное.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 24th June 2025 - 23:31
Рейтинг@Mail.ru


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