Atualmente, estou escrevendo um RTOS para microcontroladores. A coisa toda está escrita em C ++ 11 - se alguém estiver interessado, e o link para o repositório está na parte inferior.
Atualmente, estou escrevendo uma classe que é uma fila de dados simples para passar objetos entre threads (ou entre manipuladores de interrupção e threads ou manipuladores de interrupção e outros manipuladores de interrupção). Normalmente, tento seguir algumas APIs comuns encontradas em outros projetos, mas não encontrei nenhum exemplo de fila simultânea que tenha a emplace()
função AND que suporte tempos limite.
Meu "problema" geral é que não consigo decidir entre essas duas interfaces:
( std::chrono::duration<Rep, Period>
é um tipo de modelo, eu omito o modelo padrão para maior clareza)
Primeira versão:
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>);
...
}
Segunda versão:
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&&);
...
}
(haverá um segundo conjunto dessas funções com ...Until
sufixo - elas usariam o ponto no tempo em vez da duração)
A primeira versão segue um "estilo comum" de ter o tempo limite como o último parâmetro (exemplos são filas de mensagens POSIX, std::condition_variable
, filas simples em qualquer RTOS para microcontroladores). O problema é que não é possível ter esse argumento de tempo limite como o último da função tryEmplaceFor (), porque, no caso de modelos variados, os argumentos "conhecidos" devem ser os primeiros (*). Portanto, a segunda versão é "consistente" - todas as funções com tempo limite têm o tempo limite como o primeiro argumento. Essa variante tem um problema óbvio de ser provavelmente o primeiro exemplo de tempo limite como o primeiro argumento para essa funcionalidade.
Qual interface serviria melhor o sistema operacional:
- padrão estabelecido de ter o tempo limite como o último argumento (com exceção de
tryEmplaceFor()
etryEmplaceUntil()
- onde deve ser o primeiro argumento (*))? - consistência - prefere que o tempo limite seja o primeiro argumento?
(*) - Eu sei que tecnicamente eu poderia ter o tempo limite como último argumento para tryEmplaceFor()
e tryEmplaceUntil()
, mas prefiro evitar usar essa mágica de modelo para um cenário tão simples - fazer todas essas instâncias recursivas apenas para obter o último argumento parece um pouco exagerado, especialmente quando visualizo os erros que o compilador produziria caso o usuário fizesse algo errado ...