2013-08-07 1 views
0

저는 vxWorks 6.3을 실행 중이며 문제가 있습니다. RTP처럼 일련의 작업을 실행하고 있습니다. 나는 일을 만들고, 그런 다음 일을 파괴한다. 그런 다음 아주 가까이서 두 가지 작업을 만들고 물건을 만들어 파괴하십시오. 이러한 작업은 malloc 및 무료 메모리와 같은 미친 작업을 수행해야합니다. 불행히도이 작업을 충분히 수행하면 작업 중 하나가 세마포어의 메모리 (malloc 및 free 모두) 루틴에 걸리게됩니다. 그것은 항상 자유 또는 malloc에서 작업의 맨 처음에 "잃어 버리게"되는 두 번째 작업입니다. 실패한 후에도 작업을 생성 할 수 있으며 여전히 malloc 메모리를 사용할 수 있습니다. 실패한 작업은 세마포를 기다리고 영원히 기다리고 있습니다 ... 다른 작업이 반드시 사용해야하는 세마포어.VxWorks가 메모리 루틴에 걸렸습니다.

누구든지 작업이 메모리 루틴에 걸리는 방식을 알고 있습니까?

0x08265e58 malloc  +0x2c : 0x082416f4() 
0x08267e50 memPartAlloc +0x28 : 0x08241734() 
0x08267e0c memPartAlignedAlloc+0x70 : 0x08267c04() 
0x08267c7c memPartFree +0xfc : 0x08240654() 
0x082753c0 semTake  +0x90 : 0x08242534() 
0x082752ec semUMTake +0xd8 : 0x08242514() 
---- system call boundary ---- 

-> tw 0x69d21b0 
    NAME  ENTRY  TID  STATUS DELAY OBJ_TYPE OBJ_ID OBJ_NAME 
---------- ---------- ---------- ---------- ----- ---------- ---------- -------- 
tHttp631-2 0x827dbfc 0x69d21b0 PEND   0 SEM_M  0x6859650 N/A 

Semaphore Id  : 0x6859650 
Semaphore Type  : MUTEX 
Task Queuing  : PRIORITY 
Pended Tasks  : 1 
Owner    : 0x69d1a08 Deleted! 
Options    : 0xd  SEM_Q_PRIORITY 
           SEM_DELETE_SAFE 
           SEM_INVERSION_SAFE 
VxWorks Events 
-------------- 
Registered Task  : NONE 
Event(s) to Send : N/A 
Options    : N/A 
Pended Tasks 
------------ 
    NAME  TID PRI TIMEOUT 
---------- -------- --- ------- 
tHttp631-25502 69d21b0 120  0 
value = 0 = 0x0 
-> 

답변

0

몇 가지 질문 :

  • 이 모든 작업이 생성 /은 RTP 삭제하고 있습니까?
  • "작업을 어떻게 파괴합니까"?
  • 그런 다음 작업 블록은 동일한 RTP 또는 다른 RTP에서 새로운 malloc/tasks 생성입니까?
  • 전체 RTP를 삭제 하시겠습니까?

하나의 작업에서 taskDelete를 사용하여 다른 작업을 삭제하는 것처럼 들립니다. 그렇다면 메모리 작업 도중 작업이 삭제 될 수 있습니다.

이것은 RTP에서 malloc 연산이므로 생성 된 각 RTP에는 자체 힙 (malloc) 세마포가 포함되어 있습니다. 나는 이것이 개최되는 세마포어라고 생각할 것이다.

윈드 리버 지원팀에 연락하는 것이 좋습니다. 이는 익숙한 문제 일 수 있습니다.

+0

아니요, 우리는 taskDelete를 사용하고 있지 않습니다. 작업은 자신의 의무를 끝내고 호출 기능에서 돌아옵니다. 관련된 모든 작업은 동일한 RTP 프로세스에 있습니다. RTP는 계속 실행됩니다. 그것은 종료되지 않습니다. WindRiver에 연락 할 수있는 기회가 있었으면 좋지만 몇 년 전에 지원 계약을 해지했습니다. – GailG

1

초기화시 최악의 경우 메모리를 충분히 할당 한 다음 프로그램 기간 동안 메모리를 다시 사용하는 것이 좋습니다. 특히 실제로 malloc/free가 비 결정적인 작업이기 때문에 실시간 요구 사항이있는 경우 런타임에 새 작업을 다시 작성하는 대신 작업을 다시 사용하고 적절한 시간에 적절한 작업을 시작하기 위해 세마포 또는 msgQueue를 사용하는 것이 좋습니다. . 그래서 프로그램의 흐름은 다음과 같이 보일 수 있습니다

initTime() 
{ 
    t1mem = malloc(t1memSize); 
    t2mem = malloc(t2memSize); 
    t3mem = malloc(t3memSize); 
    t1q = msgQCreate(qlen, msglen, MSG_Q_FIFO); 
    t2q = msgQCreate(qlen, msglen, MSG_Q_FIFO); 
    t3q = msgQCreate(qlen, msglen, MSG_Q_FIFO); 
    rspq = msgQCreate(qlen, msglen, MSG_Q_FIFO); 
    taskSpawn("t1", t1pri, ..., t1Entry, t1mem, t1q, rspq, ...); 
    taskSpawn("t2", t2pri, ..., t2Entry, t2mem, t2q, rspq, ...); 
    taskSpawn("t3", t3pri, ..., t3Entry, t3mem, t3q, rspq, ...); 

    runTime(t1sem, t2sem, t3sem, rspq); 

    msgQDelete(t1q); 
    msgQDelete(t2q); 
    msgQDelete(t3q); 
    msgQDelete(rspq); 
    free(t1mem); 
    free(t2mem); 
    free(t3mem); 
} 

runTime(MSG_Q_ID t1q, MSG_Q_ID t2q, MSG_Q_ID t3q, MSG_Q_ID rspq) 
{ 
    while (programRun) 
    { 
     tasksDone = 0; 
     msgQSend(t1q, t1start, msglen, 100, MSG_PRI_NORMAL); 
     if (msgQReceive(rspq, buf, msglen, errorCaseTimeout) == OK) 
     { 
      // check to make sure the msg is t1done... 
      // report error if it isn't... 
      msgQSend(t2q, t2start, msglen, 100, MSG_PRI_NORMAL); 
      msgQSend(t3q, t3start, msglen, 100, MSG_PRI_NORMAL); 
      for (int x = 0; x < 2; x++) 
      { 
       if (msgQReceive(rspq, buf, msglen, errorCaseTimeout) == OK) 
       { 
        // check to make sure the msg is t2done/t3done... 
        // report error if it isn't... 
        tasksDone++; 
       } 
      } 
     } 
     if (tasksDone == 2) 
     { 
      // everything is good... keep on running... 
     } 
     else 
     { 
      // a task didnt finish within the errorCaseTimeout time... 
      // report error or something, maybe set programRun to false... 
     } 
    } 
} 

t1Entry(void* mem, MSG_Q_ID q, MSG_Q_ID rspq) 
{ 
    while (programRun) 
    { 
     if (msgQReceive(q, buf, msglen, 100) == OK) 
     { 
      doTask1(mem); 
      msgQSend(rspq, t1done, msglen, 100, MSG_PRI_NORMAL); 
     } 
    } 
} 

t2Entry(void* mem, MSG_Q_ID q, MSG_Q_ID rspq) 
{ 
    while (programRun) 
    { 
     if (msgQReceive(q, buf, msglen, 100) == OK) 
     { 
      doTask2(mem); 
      msgQSend(rspq, t2done, msglen, 100, MSG_PRI_NORMAL); 
     } 
    } 
} 

t3Entry(void* mem, MSG_Q_ID q, MSG_Q_ID rspq) 
{ 
    while (programRun) 
    { 
     if (msgQReceive(q, buf, msglen, 100) == OK) 
     { 
      doTask3(mem); 
      msgQSend(rspq, t3done, msglen, 100, MSG_PRI_NORMAL); 
     } 
    } 
} 

은 물론 위의 코드는 매우 DRY하지 않고, 모든 오류의 경우 완전히 처리하지만, 시작과 결정 론적 작업의 좋은 기회가있다.

+0

우리가 실패 상태에 빠졌을 때, 우리는 19MB의 여유가 있었고 (그 근처에 아무데도 필요하지 않음), 우리는 메모리가 부족하지 않을 것이라고 확신합니다. 간단한 "메모리 부족"이라면 콘솔에서 msg를 가져와야합니다.네, 저의 다음 시도는 바로 이것입니다. 나는 재사용 할 수있는 두 개의 스레드를 갖게 될 것입니다. 나는 몇 가지 다른 해결 방법을 시도했지만 이것은 문제를 다른 곳으로 옮기는 것으로 보인다. 나는 문제의 근본 원인을 찾기를 원했기 때문에 최종 솔루션이 실제 문제를 가리는 것이 아니라는 것을 확실하게 말할 수있었습니다. – GailG

+0

실제로, 나는 당신이 기억이 부족하다고 제안하는 것이 아니라 오히려 실시간/임베디드 시스템에서보다 보편적 인 원리를 사용하는 다른 접근 방식을 제안하고있었습니다. 이 접근법이 그것을 숨길 수있는 문제가 있다면 실제로 당신이 맞습니다. –

+0

나는 또한 위의 출력에서 ​​다음을 주목했다 : Owner : 0x69d1a08 Deleted! 슬프게도 더 이상 vxworks 시스템, 소스 또는 문서에 액세스 할 수 없습니다. 그러나 뮤텍스 소유자가 삭제되면 세마포어를 제공 할 수 없으므로 보류중인 스레드 (0x69d21b0)가 영원히 차단됩니다. –

0

다른 증상이 나타나기는하지만 이것은 내가 가지고있는 문제와 관련이있을 수 있습니다. 두 경우 모두 세마포어 소유자가 삭제됩니다. 제 경우에는 tWebTask를 정지시키고 웹 소켓에서 누락 된 세마포어 소유자를 추적합니다.

Here's the link to my SO question.