|
Альтернативный вариант задания функции процесса |
|
|
|
Nov 10 2012, 13:36
|
Частый гость
 
Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318

|
Приветствую. Начал смотреть scmRTOS. Сразу начал резать глаз способ реализации функции процесса: Код typedef OS::process<OS::pr0, 300> TProc1;
namespace OS { template <> OS_PROCESS void TProc1::exec() { for(;;) { ef.wait(); PB0.Off(); } } } Необходимость реализовывать функцию процесса внутри поля имён OS, а добавление template <> вызывает некоторое удивление Подумалось, почему-бы не сделать ф-цию exec просто ф-цией своего собственного класса? На скорую руку сделал несколько изменений в исходниках scmRTOS и весь код декларации и реализации процесса превратился в: Код class TProc1 : public OS::process<TProc1, OS::pr0, 300> { public: static void exec() { for(;;) { ef.wait(); PB0.Off(); } } }; Что мы в итоге имеем? 1) Класс, в котором можно инкапсулировать данные и методы процесса. Закрытые и используемые только в TProc1 данные можно объявить в секции private класса и никто к ним не получит доступ. 2) Более привычный способ реализации ф-ции. Кто что думает на этот счёт?
--------------------
|
|
|
|
|
 |
Ответов
|
Nov 14 2012, 01:17
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
QUOTE (AHTOXA @ Nov 14 2012, 00:04)  Ладно, раз уж у Гарри такая идиосинкразия к этому варианту, то давайте сделаем его расширением. Я попробовал, оказывается это работает точно так же  Вот, приаттачу пока сюда, а на днях выложу в репозиторий (Уж здесь-то, я думаю, возражений не последует?). [attachment=72666:CustomProcess.h.zip] Э-э, мы, вроде, договорились, что если реализация не страдает, то принимаем. Т.ч. это можно не расширением, а основным вариантом делать. Клади в trunk, попробуем при случае. QUOTE (ReAl @ Nov 14 2012, 01:44)  Хотя нынешний процесс -- скорее шасси, на которое можно пассажирскую газельку навесить, можно бортовую. Предлагается только вариант на шлее тянуть за этим шасси телегу. Да, скорее просто платформа для перевозки. Проблема в том, она не очень хорошо переделывается ни в полноценный грузовик, ни в автобус (из-за статика). QUOTE (ReAl @ Nov 14 2012, 01:44)  Ну да. Только я считаю абсолютно полноправным (равноправным с другими) вариант CODE class Тгрузовик : public Ттранспорт; class Тавтобус : public Ттранспорт; И не считаю, что всегда и везде единственно правильно CODE class Тгрузовик { public: едь(); }; Ттранспорт<..> транспорт1; Тгрузовик грузовик; транспорт1::толкай() { грузовик.едь(); } Да, это хорошая схема, годная, против такой я бы не возражал. Вот если получится это: QUOTE (AHTOXA @ Nov 14 2012, 00:04)  И ещё попробую сделать вариант с нестатическим exec(). Тоже в виде расширения. Чтоб уж совсем была инкапсуляция  то тогда в корне пересмотрим подход. Почему там статик, я сейчас уже не помню, то ли что-то не получалось по-иному сделать, то ли тогда видение было таким, идеология. Исторически сложилось. Исходно упор был на минимизацию и лёгкость, нынче времена меняются, можно и основные концепции пересмотреть в каких-то пределах. QUOTE (ReAl @ Nov 14 2012, 01:44)  Может, я наглухо испорчен борландсишным CODE class TMyThread : public TThread { protected: virtual void execute(); // А в этой теме предлагается вместо virtual передать базе тип потомка но мне это не кажется настолько ненормальным, что нельзя это добавить в саму ОС. Другое дело, если бы это ломало все существующие наработки, но оно же прозрачно для старых проектов. И не у меня последнего такая хотелка, как видим. Ну, с методами (виртуальными функциями) в борланде всё понятно - там-то это как правило именно тред - поток управления, который имеет начало и конец - вызвали его, он отработал и кончился. И тут нужна гибкость при вызове, чтобы можно строить элегантные схемы с обработкой - вызывать автоматом нужный в каждом контексте метод. Это не про нас. Что касается самой схемы передачи типа объекта аргументом шаблона, который участвует в наследовании, то это основа для создания стратегий (Александреску). Это достаточно глубокая вещь. В данном же случае это просто синтаксический выверт, и как ты выражаешься: "страдает моё чувство прекрасного".  Но как уже сказал выше, раз с совместимостью и кодогенерацией никаких проблем нет, пусть будет этот вариант, если он кому-то больше нравится (хотя я не вижу, повторяю, в этом особого смысла - инкапсулированного объекта не получается, придётся руками объявлять все поля-данные вне пределов класса и т.д.).
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Nov 14 2012, 08:46
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Сергей Борщ @ Nov 14 2012, 09:29)  то указатель был бы на функцию-член, а он совсем другой и зависящий от реализации. Рассуждаю. А если сделать дополнительную статическую функцию, скажем, start(), с параметром типа "тип процесса", в init_stack_frame() использовать ее вместо exec, в стековый фрейм на место регистра, в котором передается параметр, класть this, А функция уже будет делать param->exec(). Т.е. мы не вдаемся в дебри реализации указателя на функцию-член, этим занимается компилятор в start(), exec может быть нестатическим. Как-то так... Еще неплохо бы объявить exec как noreturn, чтобы компилятор догалася заменить вызов exec() на переход в нее. В принципе, такое изменение достойно релиза 4.1. И продумать совместимость с текущими исходниками.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 15 2012, 19:49
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Я вот что подумал. В момент вызова TBaseProcess::init_stack_frame() у нас уже гарантированно имеется в нужных регистрах указатель на TBaseProcess. Таким образом, ничего формировать не надо, достаточно лишь честно сохранить контекст, подменив PC адресом начала функции-члена exec(). Для пробы можно сделать в конструкторе наследника, как-то так: Код class BaseVirtualProcess : public TBaseProcess { public: INLINE_PROCESS_CTOR BaseVirtualProcess(stack_item_t * StackPoolEnd, TPriority pr) : TBaseProcess(StackPoolEnd, pr, 0 // - не нужен) { reinit_stack_frame(); } protected: OS_PROCESS virtual void exec() {}; // это наш виртуальный exec() private: void reinit_stack_frame() { StackPointer += 16; // отменим деятельность TBaseProcess::init_stack_frame() *(--StackPointer) = 0x01000000L; // xPSR *(--StackPointer) = reinterpret_cast<uint32_t>(&exec); // вот здесь адрес виртуального exec // и тут честно сохраняем остальные регистры, в том числе и self. (наверное будет ассемблерная процедура в порте) } }; Правда reinterpret_cast здесь не проходит, надо какой-то ещё способ получить адрес exec(). --- Добавлю ссылочку про получение адреса функции-члена. На завтра
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
Сообщений в этой теме
ArtDenis Альтернативный вариант задания функции процесса Nov 10 2012, 13:36 AHTOXA Цитата(ArtDenis @ Nov 10 2012, 19:36) Что... Nov 10 2012, 15:59 ArtDenis AHTOXA, по идее вообще никак не должно влиять на б... Nov 10 2012, 16:10 AHTOXA Ну что я могу сказать... Мне очень понравилось. Эт... Nov 10 2012, 16:31 dxp QUOTE (ArtDenis @ Nov 10 2012, 20:36) Нео... Nov 11 2012, 03:21 ArtDenis Цитата(dxp @ Nov 11 2012, 09:21) Откуда в... Nov 11 2012, 05:00 AHTOXA Цитата(dxp @ Nov 11 2012, 09:21) Уже обсу... Nov 11 2012, 06:07 dxp QUOTE (ArtDenis @ Nov 11 2012, 12:00) А к... Nov 11 2012, 12:02 ArtDenis Цитата(dxp @ Nov 11 2012, 18:02) Я не зна... Nov 11 2012, 12:43  dxp QUOTE (ArtDenis @ Nov 11 2012, 19:43) Я с... Nov 11 2012, 13:00 AHTOXA Цитата(dxp @ Nov 11 2012, 19:00) Помещать... Nov 11 2012, 16:00 AHTOXA Йоу! Я придумал, как совместить эти два вариан... Nov 11 2012, 19:15  ArtDenis Цитата(AHTOXA @ Nov 12 2012, 01:15) Йоу... Nov 12 2012, 02:41  Сергей Борщ QUOTE (AHTOXA @ Nov 11 2012, 21:15) Я при... Nov 12 2012, 07:13   AHTOXA Цитата(Сергей Борщ @ Nov 12 2012, 13:13) ... Nov 12 2012, 07:48    Сергей Борщ QUOTE (AHTOXA @ Nov 12 2012, 09:48) Не по... Nov 12 2012, 07:56     AHTOXA А может мои пламенные речи уже переубедили его? Nov 12 2012, 10:25   ArtDenis Цитата(Сергей Борщ @ Nov 12 2012, 13:13) ... Nov 12 2012, 15:08 ReAl Цитата(ArtDenis @ Nov 11 2012, 07:00) Лич... Nov 11 2012, 20:07 dxp QUOTE (AHTOXA @ Nov 11 2012, 23:00) Вообщ... Nov 13 2012, 06:20 AHTOXA Цитата(dxp @ Nov 13 2012, 12:20) В общем,... Nov 13 2012, 14:06 ArtDenis Цитата(dxp @ Nov 13 2012, 12:20) Ни разу ... Nov 13 2012, 15:59 ReAl Цитата(Сергей Борщ @ Nov 12 2012, 09:13) ... Nov 13 2012, 15:31 Сергей Борщ QUOTE (ReAl @ Nov 13 2012, 17:31) А как и... Nov 13 2012, 16:34 dxp QUOTE (AHTOXA @ Nov 13 2012, 21:06) Прове... Nov 13 2012, 16:52 AHTOXA Ладно, раз уж у Гарри такая идиосинкразия к этому ... Nov 13 2012, 17:04 ReAl Цитата(dxp @ Nov 13 2012, 18:52) Отождест... Nov 13 2012, 18:44 ArtDenis Цитата(dxp @ Nov 13 2012, 22:52) Вы путае... Nov 14 2012, 03:33  ReAl Цитата(ArtDenis @ Nov 14 2012, 05:33) В о... Nov 14 2012, 13:45   ArtDenis Цитата(ReAl @ Nov 14 2012, 19:45) Ну да.
... Nov 14 2012, 14:00    ReAl Цитата(ArtDenis @ Nov 14 2012, 16:00) voi... Nov 14 2012, 15:01     ArtDenis Цитата(ReAl @ Nov 14 2012, 21:01) -Wredun... Nov 14 2012, 15:21 AHTOXA Цитата(dxp @ Nov 14 2012, 07:17) Э-э, мы,... Nov 14 2012, 07:47 dxp QUOTE (Сергей Борщ @ Nov 14 2012, 15:46) ... Nov 14 2012, 11:57 ReAl Цитата(dxp @ Nov 14 2012, 13:57) Кстати, ... Nov 14 2012, 12:51 ArtDenis Всё-таки расставлю точки над i по поводу текущего ... Nov 14 2012, 13:43 ReAl Не надо адрес функции-члена... Слова C++ extension... Nov 15 2012, 20:19 ArtDenis AHTOXA, Указатель на нестатическую функцию член кл... Nov 16 2012, 03:41 AHTOXA Цитата(ArtDenis @ Nov 16 2012, 09:41) AHT... Nov 16 2012, 19:41 AHTOXA Я так понимаю, никто не впечатлился?
Да, это оч... Nov 17 2012, 20:10 Vasya777 Предлагаю другой вариант
Пользовательские классы
... Mar 20 2013, 16:59
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|