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 ...Untilsufiksem - 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 ...