/********************************************************************************************************* ** 函数名称: __selPtyAdd ** 功能描述: 向指定的 pty wake up list 添加一个等待节点. (ioctl FIOSELECT 使用) ** 输 入 : p_ptyddev Ty 虚拟设备控制块 lArg select wake up node 控制结构 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID __selPtyAdd (P_PTY_D_DEV p_ptyddev, LONG lArg) { REGISTER TY_DEV_ID ptyDev; REGISTER PLW_SEL_WAKEUPNODE pselwunNode = (PLW_SEL_WAKEUPNODE)lArg; REGISTER P_PTY_H_DEV p_ptyhdev = (P_PTY_H_DEV)_LIST_ENTRY(p_ptyddev, PTY_DEV, PTYDEV_ptyddev); /* 获得 HOST 端口 */ ptyDev = &p_ptyhdev->PTYHDEV_tydevTyDev; SEL_WAKE_NODE_ADD(&p_ptyddev->PTYDDEV_selwulList, pselwunNode); /* 添加节点 */ switch (pselwunNode->SELWUN_seltypType) { case SELREAD: /* 等待数据可读 */ if ((rngNBytes(ptyDev->TYDEV_vxringidWrBuf) > 0) || (ptyDev->TYDEV_tydevwrstat.TYDEVWRSTAT_bCR)) { SEL_WAKE_UP(pselwunNode); /* 检测主机是否有数据需要发送 */ } else { ptyDev->TYDEV_tydevwrstat.TYDEVWRSTAT_bBusy = LW_FALSE; /* 确保可以被 Startup 激活 */ } break; case SELWRITE: /* 等待数据可写 */ if (rngFreeBytes(ptyDev->TYDEV_vxringidRdBuf) > 0) { /* 检测主机接收缓存是否有空间 */ SEL_WAKE_UP(pselwunNode); /* 唤醒节点 */ } break; case SELEXCEPT: /* 等待设备异常 */ if ((LW_DEV_GET_USE_COUNT(&p_ptyddev->PTYDDEV_devhdrDevice) == 0) || (LW_DEV_GET_USE_COUNT(&p_ptyhdev->PTYHDEV_tydevTyDev.TYDEV_devhdrHdr) == 0)) { /* 设备关闭了 */ SEL_WAKE_UP(pselwunNode); /* 唤醒节点 */ } break; } }
static void rootTask(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { int j, res, k, chunks; const int putBytes = 10; const int nrChunks = 3; const int rngBytes = putBytes * nrChunks; char buffer[putBytes]; char bigBuffer[putBytes * 2 * nrChunks]; int bytesPut; int bytesGot; int expectedCounter = 0; int checkCounter = 0; RING_ID rng; char not_a_ring[32]; traceobj_enter(&trobj); ADD_CONTENT(buffer, sizeof(buffer), expectedCounter); rng = rngCreate(1); traceobj_assert(&trobj, rngIsEmpty(rng)); memset(buffer, 0, sizeof(buffer)); buffer[0] = 17; rngBufPut(rng, buffer, 1); traceobj_assert(&trobj, rngIsFull(rng)); rngBufGet(rng, buffer, 1); traceobj_assert(&trobj, rngIsEmpty(rng)); buffer[0] = 34; rngBufPut(rng, buffer, 1); traceobj_assert(&trobj, rngIsFull(rng)); expectedCounter = 0; rngDelete(rng); /* Here real vxWorks 6.6 just return ERROR */ memset(not_a_ring, 0, sizeof(not_a_ring)); errnoSet(0); res = rngBufPut((RING_ID) & not_a_ring[0], buffer, 1); traceobj_assert(&trobj, res == ERROR); /* rng = rngCreate(1 * 1024 * 1024 * 1024); traceobj_assert(&trobj, res == ERROR); traceobj_assert(&trobj, errnoGet() == S_memLib_NOT_ENOUGH_MEMORY); */ rng = rngCreate(rngBytes); traceobj_assert(&trobj, rng != 0); traceobj_assert(&trobj, rngIsEmpty(rng)); traceobj_assert(&trobj, !rngIsFull(rng)); /* Fill a few chunks */ for (chunks = 0; chunks < nrChunks; chunks++) { traceobj_assert(&trobj, rngNBytes(rng) == chunks * (int)sizeof(buffer)); traceobj_assert(&trobj, rngFreeBytes(rng) == rngBytes - chunks * (int)sizeof(buffer)); for (j = 0; j < (int)sizeof(buffer); j++) { buffer[j] = (char)j + (int)sizeof(buffer) * chunks; } ADD_CONTENT(buffer, sizeof(buffer), checkCounter); bytesPut = rngBufPut(rng, &buffer[0], sizeof(buffer)); traceobj_assert(&trobj, bytesPut == sizeof(buffer)); traceobj_assert(&trobj, !rngIsEmpty(rng)); traceobj_assert(&trobj, rngIsFull(rng) == (nrChunks - 1 == chunks)); traceobj_assert(&trobj, rngFreeBytes(rng) == rngBytes - bytesPut * (chunks + 1)); traceobj_assert(&trobj, rngNBytes(rng) == (chunks + 1) * (int)sizeof(buffer)); } traceobj_assert(&trobj, rngIsFull(rng)); ADD_CONTENT(buffer, sizeof(buffer), checkCounter); bytesPut = rngBufPut(rng, &buffer[0], sizeof(buffer)); traceobj_assert(&trobj, bytesPut == 0); traceobj_assert(&trobj, rngIsFull(rng)); /* Read chunks back and check content */ for (chunks = 0; chunks < nrChunks; chunks++) { memset(buffer, 0, sizeof(buffer)); traceobj_assert(&trobj, rngNBytes(rng) == (nrChunks - chunks) * (int)sizeof(buffer)); traceobj_assert(&trobj, rngFreeBytes(rng) == chunks * (int)sizeof(buffer)); bytesGot = rngBufGet(rng, &buffer[0], sizeof(buffer)); traceobj_assert(&trobj, bytesGot == (int)sizeof(buffer)); CHECK_CONTENT(buffer, bytesGot, expectedCounter); traceobj_assert(&trobj, !rngIsFull(rng)); traceobj_assert(&trobj, rngIsEmpty(rng) == (chunks == nrChunks - 1)); traceobj_assert(&trobj, rngFreeBytes(rng) == (chunks + 1) * (int)sizeof(buffer)); traceobj_assert(&trobj, rngNBytes(rng) == (nrChunks - chunks - 1) * (int)sizeof(buffer)); } /* Testing filling too many */ ADD_CONTENT(bigBuffer, sizeof(bigBuffer), checkCounter) bytesPut = rngBufPut(rng, &bigBuffer[0], sizeof(bigBuffer)); traceobj_assert(&trobj, bytesPut == rngBytes); traceobj_assert(&trobj, !rngIsEmpty(rng)); traceobj_assert(&trobj, rngIsFull(rng)); traceobj_assert(&trobj, rngFreeBytes(rng) == 0); traceobj_assert(&trobj, rngNBytes(rng) == rngBytes); /* Getting too many */ memset(bigBuffer, 0, sizeof(bigBuffer)); bytesGot = rngBufGet(rng, &bigBuffer[0], sizeof(bigBuffer)); traceobj_assert(&trobj, bytesGot == rngBytes); traceobj_assert(&trobj, rngIsEmpty(rng)); traceobj_assert(&trobj, !rngIsFull(rng)); traceobj_assert(&trobj, rngFreeBytes(rng) == rngBytes); traceobj_assert(&trobj, rngNBytes(rng) == 0); /* Now we need to adjust our expectedCounter */ expectedCounter += sizeof(buffer); CHECK_CONTENT(bigBuffer, bytesGot, expectedCounter); ADD_CONTENT(bigBuffer, sizeof(bigBuffer), checkCounter); bytesPut = rngBufPut(rng, &bigBuffer[0], sizeof(bigBuffer)); traceobj_assert(&trobj, bytesPut == rngBytes); rngFlush(rng); traceobj_assert(&trobj, rngIsEmpty(rng)); traceobj_assert(&trobj, !rngIsFull(rng)); traceobj_assert(&trobj, rngFreeBytes(rng) == rngBytes); traceobj_assert(&trobj, rngNBytes(rng) == 0); while (bytesGot > 0) { bytesGot = rngBufGet(rng, &bigBuffer[0], sizeof(bigBuffer)); CHECK_CONTENT(bigBuffer, bytesGot, expectedCounter); } rngDelete(rng); chunks = 10; rng = rngCreate(chunks); bytesPut = 5; traceobj_assert(&trobj, rngFreeBytes(rng) > bytesPut); checkCounter = 0xaa; expectedCounter = checkCounter; for (j = 0; j < bytesPut; j++) { rngPutAhead(rng, checkCounter, j); checkCounter++; } rngMoveAhead(rng, bytesPut); bytesGot = rngBufGet(rng, &bigBuffer[0], sizeof(bigBuffer)); traceobj_assert(&trobj, bytesGot == bytesPut); CHECK_CONTENT(bigBuffer, bytesGot, expectedCounter); /* Check also wrap-around */ bytesPut = chunks -2; traceobj_assert(&trobj, rngFreeBytes(rng) > bytesPut); checkCounter = 0xaa; expectedCounter = checkCounter; for (j = 0; j < bytesPut; j++) { rngPutAhead(rng, checkCounter, j); checkCounter++; } rngMoveAhead(rng, bytesPut); bytesGot = rngBufGet(rng, &bigBuffer[0], sizeof(bigBuffer)); traceobj_assert(&trobj, bytesGot == bytesPut); CHECK_CONTENT(bigBuffer, bytesGot, expectedCounter); rngDelete(rng); traceobj_exit(&trobj); }