Fila de mensagens para RTOS para microcontroladores

10

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 ...Untilsufixo - 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()e tryEmplaceUntil()- 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 ...


Freddie Chopin
fonte
Qual é a diferença entre a primeira e a segunda versão? Por favor, destaque.
JBRWilkinson
1
Observação: nem todo mundo conhece o POSIX o suficiente para se incomodar com a colocação do tempo, mas todos que usam sua interface ficam frustrados com a API inconsistente. Eu voto no 2.
J Trana

Respostas:

0

Conforme sugerido por uma resposta que foi excluída (infelizmente) e comentários, segui a linha "consistência" (segunda variante apresentada) - em todas as funções "try ... For" e "try ... Até" o tempo limite (duration ou ponto no tempo) é o primeiro argumento.

Este é o código no estágio atual - link

Freddie Chopin
fonte