0

我正在运行 vxWorks 6.3 并遇到了问题。我有一系列任务在 RTP 中运行。我创建一个任务,做一些事情然后销毁这个任务。然后创建两个非常接近的任务,做一些事情并销毁它们。这些任务必须做一些疯狂的事情,比如 malloc 和释放内存。不幸的是,如果我这样做的次数足够多,其中一项任务将卡在信号量上的内存(malloc 和 free)例程中。在 free 或 malloc 中,它总是在任务开始时“丢失”的第二个任务。失败后,我仍然可以创建任务,我仍然可以 malloc 内存。失败的任务永远存在,等待信号量......其他任务必须使用的信号量。

有谁知道任务是如何卡在记忆例程中的?

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
->
4

3 回答 3

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);
        }
    }
}

显然,上面的代码不是很,也不是所有的错误情况都得到了完全处理,但它是一个开始,并且很有可能确定性地工作。

于 2013-08-10T09:14:45.287 回答
0

这可能与我遇到的问题有关,尽管我看到了不同的症状。在这两种情况下,信号量的所有者都将被删除。就我而言,我让 tWebTask 挂起并将其跟踪到 Web 套接字上丢失的信号量所有者。

这是我的 SO question 的链接

于 2013-09-25T20:55:54.673 回答
0

几个问题:

  • 是否在 RTP 中创建/删除了所有任务?
  • 你是如何“破坏任务”的?
  • 那么当任务阻塞时,是在同一个 RTP 还是不同的 RTP 中创建新的 malloc/任务?
  • 您要删除整个 RTP 吗?

听起来您正在使用一个任务中的 taskDelete 来销毁其他任务。如果是这种情况,则有可能在内存操作过程中删除了任务。

由于这是 RTP 中的 malloc 操作,因此创建的每个 RTP 都包含它自己的堆 (malloc) 信号量。我认为这将是所持有的信号量。

我建议联系风河支持。这可能是他们熟悉的问题。

于 2013-08-08T02:48:31.110 回答