문제

나는 서로에게 메시지를 보내는 여러 작업으로 구성된 C에서 임베디드 제어 시스템을 작성하고 있습니다 (상당히 일반적인 관용구, 믿습니다!).

  • 깔끔합니다
  • 일반적입니다
  • 비교적 효율적입니다
  • 가장 중요한 것은: 플랫폼 독립적입니다 (특히, 엄격한 알리 아스 또는 정렬 문제를 위반하지 않음)

개념적으로, 각 메시지 유형을 별도의 구조물 정의로 표현하고 싶습니다. 다음 기능 (단순화)이있는 시스템을 원합니다.

void sendMsg(queue_t *pQueue, void *pMsg, size_t size);
void *dequeueMsg(queue_t *pQueue);

여기서 a queue_t 각각 링크 된 노드 목록으로 구성되며 각각 char buf[MAX_SIZE] 필드. 내가 켜져있는 시스템에는 없습니다 malloc() 구현, 따라서 전역의 자유 노드 풀이 있어야하고 다음 중 하나 (대담한 문제) 중 하나가 필요합니다.

  1. sendMsg() a memcpy 수신 메시지의 자유 노드의 버퍼에.
    내 이해는 발신자가 의지하지 않는 한 조정 문제가 있다는 것입니다 dequeueMsg() 더합니다 memcpy 반환 값에서.
  2. 아니면있을 것입니다 void *getFreeBuffer() 반환하는 함수 buf[] 발신자 (발신자)가 적절한 포인터-타입으로 캐스팅되는 다음 자유 노드의 경우.
    내 이해는 이것이 이제 정렬 문제가있을 것이며 여전히 필요하다는 것입니다. memcpy ~ 후에 dequeueMsg() 나가는 길에 정렬 문제를 피하기 위해.
  3. 또는 버퍼를 재정의하십시오 queue_t 노드 AS (예 :) uint32_t buf[MAX_SIZE].
    내 이해는 이것이 엄격한 별칭을 위반하고 플랫폼 독립적이지 않다는 것입니다.

내가 볼 수있는 유일한 다른 옵션은 char buf[MAX_SIZE], 그러나 나는 이것을 "깔끔한"것으로 간주하지 않습니다!

그래서 내 질문은 어떻게 제대로 제대로 수행합니까?

도움이 되었습니까?

해결책

우리가 이것을 다루는 방법은 무료 목록이 전적으로 정렬 된 노드로 구성되는 것입니다. 실제로 우리는 다른 크기의 노드에 대한 여러 개의 무료 목록이 있으므로 2 바이트, 4 바이트 및 16 바이트 경계에 정렬되는 목록이 있습니다 (플랫폼은 하나의 SIMD 벡터보다 큰 정렬에 신경 쓰지 않습니다). 할당은 해당 값 중 하나까지 반올림되어 올바르게 정렬 된 노드를 넣습니다. 따라서 SendMSG는 항상 데이터를 정렬 된 노드로 복사합니다. 무료 목록을 직접 작성하므로 정렬을 쉽게 시행 할 수 있습니다.

또한 #pragma 또는 declspec을 사용하여 해당 char buf [max_size] 배열이 queue_t 노드 구조물 내부의 단어 경계에 정렬되도록 강요합니다.

이것은 물론 입력 데이터가 정렬되었다고 가정하지만 어떤 이유로 든 메시지를 전달합니다. 기대합니다 정렬에서 3 바이트 오프가 되려면 항상 모듈러스로이를 감지하고 오프셋을 자유 노드로 반환 할 수 있습니다.

그 기본 디자인으로 우리는 위의 옵션 1과 2를 모두 지원하는 인터페이스가 있습니다. 다시, 우리는 입력 데이터가 항상 기본적으로 정렬된다는 전제 조건이므로, 우리의 탈수는 정렬 된 포인터를 반환합니다. 그러나 다시 정렬 된 데이터가 필요하면 다시 자유 노드로 오프셋하고 오프셋 포인터를 반환하십시오.

이것은 당신이 무효 *를 처리하여 엄격한 별칭 문제를 피할 수있게합니다. (일반적으로 나는 자신의 메모리 할당자를 작성할 때 엄격한 별칭 요구 사항을 완화해야 할 수도 있지만, 본질적으로 내부적으로 유형을 흐리게하므로).

다른 팁

나는 이유를 이해하지 못한다 1 정렬 문제를 제시합니다 buf[MAX_SIZE] 요소는 메시지 structs (아마도 32 또는 64 비트)에서 발생하는 자연스러운 최대 단일 원시 유형에 정렬되며 각 메시지 유형의 내용이 무엇인지는 중요하지 않습니다. 항상 해당 크기에 맞게 정렬됩니다.

편집하다

실제로, 그것보다 훨씬 간단합니다. 메시지 대기열의 각 요소와 같이 MAX_SIZE 길이는 각 메시지를 자신의 메시지로 시작한다고 가정합니다. buf (즉, 메시지가 <max_size 인 경우 포장하지 않습니다) 큐의 모든 메시지는 적어도 그 자체만큼 큰 경계에서 시작되므로 항상 올바르게 정렬됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top