Obecnie piszę RTOS dla mikrokontrolerów. Wszystko napisano w C ++ 11 - jeśli ktoś jest zainteresowany, a link do repozytorium znajduje się na dole.
Obecnie piszę klasę, która jest prostą kolejką danych do przekazywania obiektów między wątkami (lub między programami obsługi przerwań a wątkami lub programami obsługi przerwań i innymi programami obsługi przerwań). Zwykle staram się śledzić niektóre popularne interfejsy API znalezione w innych projektach, ale nie znalazłem żadnego przykładu współbieżnej kolejki, która ma emplace()
funkcję ORAZ obsługuje limity czasu.
Mój ogólny „problem” polega na tym, że nie mogę zdecydować między tymi dwoma interfejsami:
( std::chrono::duration<Rep, Period>
jest szablonem, dla jasności pomijam szablonowy szablon)
Pierwsza wersja:
template<typename T>
class FifoQueue
{
public:
...
template<typename... Args>
int tryEmplaceFor(std::chrono::duration<Rep, Period>, Args&&... args);
int tryPopFor(T&, std::chrono::duration<Rep, Period>);
int tryPushFor(const T&, std::chrono::duration<Rep, Period>);
int tryPushFor(T&&, std::chrono::duration<Rep, Period>);
...
}
Druga wersja:
template<typename T>
class FifoQueue
{
public:
...
template<typename... Args>
int tryEmplaceFor(std::chrono::duration<Rep, Period>, Args&&... args);
int tryPopFor(std::chrono::duration<Rep, Period>, T&);
int tryPushFor(std::chrono::duration<Rep, Period>, const T&);
int tryPushFor(std::chrono::duration<Rep, Period>, T&&);
...
}
(pojawi się drugi zestaw tych funkcji z ...Until
sufiksem - używają one punktu czasowego zamiast czasu trwania)
Pierwsza wersja ma „wspólny styl” polegający na tym, że limit czasu jest ostatnim parametrem (przykładami są kolejki komunikatów POSIX std::condition_variable
, proste kolejki w dowolnym RTOS dla mikrokontrolerów). Problem polega na tym, że nie można ustawić argumentu limitu czasu jako ostatniego dla funkcji tryEmplaceFor (), ponieważ w przypadku szablonów variadic „znane” argumenty muszą być pierwsze (*). Tak więc druga wersja jest „spójna” - wszystkie funkcje z limitem czasu mają limit czasu jako pierwszy argument. Ten wariant ma oczywisty problem z byciem prawdopodobnie pierwszym przykładem przekroczenia limitu czasu jako pierwszego argumentu za taką funkcjonalnością.
Który interfejs lepiej służy systemowi operacyjnemu:
- ustanowiono standard, w którym limit czasu jest ostatnim argumentem (z wyjątkiem
tryEmplaceFor()
itryEmplaceUntil()
- gdzie musi to być pierwszy argument (*))? - spójność - wolisz, aby limit czasu był pierwszym argumentem?
(*) - Wiem, że technicznie mógłbym mieć limit czasu jako ostatni argument tryEmplaceFor()
i tryEmplaceUntil()
, ale wolałbym unikać używania takiej magii szablonów w tak prostym scenariuszu - wykonywanie tych rekurencyjnych instancji tylko po to, aby uzyskać ostatni argument, wydaje się nieco przesadne, zwłaszcza gdy wizualizuję kompilator błędów, który wystąpiłby na wypadek, gdyby użytkownik zrobił coś złego ...