gcc를 사용하는 단일 프로세서 32 비트 마이크로 컨트롤러 용 코드를 작성했습니다.중요한 섹션에서 메모리 액세스에 volatile 키워드를 사용해야합니까?
링크 된 목록에서 타임 스탬프 개체를 사용해야합니다. 비동기적일 수있는 코드의 다른 부분 (아마도 ISR에서)이이를 목록에 추가합니다.
임계 영역은 인터럽트를 해제하고 barrier()
기능을 사용하여 구현됩니다.
gcc 최적화가 목록 항목 (제거 할 다음 항목, 목록 헤드 또는 무료 목록)에 대한 포인터를 캐싱하여 코드를 손상시킬 수있는 곳에서는 혼란 스럽습니다. while 루프 안의 어떤 것도 루프 이전의 시간에서 캐시되기를 원하지 않습니다. 메모리 장벽은 컴파일러가 함수를 시작할 때 한 번 포인터를로드하고 결코 다시로드하지 않기로 결정할 수 있습니까? 이러한 모든 목록 포인터는 생산자 코드의 중요 섹션에서 수정할 수 있습니다 (표시되지 않음). 예를 들어, pqueue_first
이 휘발성 포인터 여야하는지 이해하려고합니다.
아마도 루프가없는 경우 (목록에 추가하는 경우), 함수의 모든 코드가 중요한 섹션에 있다면 괜찮습니까?
휘발성 또는 중요한 섹션에 대한 일반적인 기사를 가리 키지 말아주세요. 그 중 일부는 읽었으므로이 특정 코드에 적용하는 방법을 보면서 문제가 있습니다. 휘발성 변수는 참조 될 때마다 컴파일러가 변수를 다시로드하도록 보장합니다. 그러나 최적화 가능성과 메모리 장벽과의 상호 작용 가능성을 이해하지 못합니다.
typedef struct {
EV_EventQueueEntry_t *pqueue_alloc; // allocation (never changes)
EV_EventQueueEntry_t *pqueue_head; // head of active queue (ISR can change it)
EV_EventQueueEntry_t *pqueue_free; // head of free list (ISR can change it)
EV_EventQueueEntry_t *pqueue_first; // soonest item in queue (ISR can change it)
EV_EventQueueEntry_t *pqueue_first_prev; // back pointer from soonest item (ISR can change it)
EV_UInt_t max_event_count;
} EV_EventQueue_t;
void RunLoop(EV_EventQueue_t *pev)
{
while(not timeout)
{
// Enter critical section
disable_interrupts();
barrier();
// item with most recent timestamp
// this can be changed by ISR add to queue operation
EV_EventQueueEntry_t *pfirst = pev->pqueue_first;
if(pfirst!=NULL && EV_PortIsFutureTime(pfirst->event.timestamp, EV_PortGetTime()))
{
// Copy out message
EV_Event_t e = pfirst->event;
// Remove event from queue
if(pev->pqueue_first_prev != NULL)
pev->pqueue_first_prev->pnext = pfirst->pnext;
else
pev->pqueue_head = pfirst->pnext;
// Put event back on free list
pfirst->pnext = pev->pqueue_free;
pev->pqueue_free = pfirst;
pfirst->event.message.type = EV_MESSAGE_NULL;
// Find next soonest message to process after this one
pev->pqueue_first = ...;
pev->pqueue_first_prev = ...; // back pointer
// Exit critical section
barrier();
enable_interrupts();
// Dispatch message
...
}
else
{
// Exit critical section
barrier();
enable_interrupts();
// waste some time
...
}
}
}
첫 번째 질문은 'barrier'기능이 모든 프로세서와 운영 체제에 대해 정의되고 표준화되었는지 여부입니다. 그렇지 않은 경우 두 번째 질문은 다음과 같습니다. 사용중인 특정 프로세서 및 운영 체제에 대한 공식 설명서는 어디에 있습니까? – user3386109
barrier 함수는 아래 답변에서와 같이'__asm__ __volatile__ ("": : "memory")'을 출력하는 것으로 보입니다. 이것은 AVR32입니다. – Robotbugs
참고 : 장벽 내에서 오래 걸리는 것처럼 보입니다. – chux