/* pipe.c - test microkernel target pipe APIs under VxMicro */ /* * Copyright (c) 2012-2014 Wind River Systems, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1) Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2) Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3) Neither the name of Wind River Systems nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* DESCRIPTION This modules tests the following target pipe routines: task_pipe_put(), task_pipe_put_wait(), task_pipe_put_wait_timeout() task_pipe_get(), task_pipe_get_wait(), task_pipe_get_wait_timeout() The following target pipe routine does not yet have a test case: task_pipe_put_async() */ /* includes */ #include #include #include #include /* defines */ #define NELEMENTS(x) (sizeof(x) / sizeof(x[0])) #define ONE_SECOND (sys_clock_ticks_per_sec) #define IRQ_PRIORITY 3 #define PIPE_SIZE 256 /* This must match the value in the VPF file */ /* typedefs */ typedef struct { int size; /* number of bytes to send/receive */ K_PIPE_OPTION options; /* options for task_pipe_XXX() APIs */ int sent; /* expected # of bytes sent */ int rcode; /* expected return code */ } SIZE_EXPECT; /* locals */ static char txBuffer[PIPE_SIZE + 32]; static char rxBuffer[PIPE_SIZE + 32]; static SIZE_EXPECT all_N[] = { {0, _ALL_N, 0, RC_FAIL}, {1, _ALL_N, 1, RC_OK}, {PIPE_SIZE - 1, _ALL_N, PIPE_SIZE - 1, RC_OK}, {PIPE_SIZE, _ALL_N, PIPE_SIZE, RC_OK}, {PIPE_SIZE + 1, _ALL_N, 0, RC_FAIL} }; static SIZE_EXPECT many_all_N[] = { {PIPE_SIZE / 3, _ALL_N, PIPE_SIZE / 3, RC_OK,}, {PIPE_SIZE / 3, _ALL_N, PIPE_SIZE / 3, RC_OK,}, {PIPE_SIZE / 3, _ALL_N, PIPE_SIZE / 3, RC_OK,}, {PIPE_SIZE / 3, _ALL_N, 0, RC_FAIL} }; static SIZE_EXPECT one_to_N[] = { {0, _1_TO_N, 0, RC_FAIL}, {1, _1_TO_N, 1, RC_OK}, {PIPE_SIZE - 1, _1_TO_N, PIPE_SIZE - 1, RC_OK}, {PIPE_SIZE, _1_TO_N, PIPE_SIZE, RC_OK}, {PIPE_SIZE + 1, _1_TO_N, PIPE_SIZE, RC_OK} }; static SIZE_EXPECT many_one_to_N[] = { {PIPE_SIZE / 3, _1_TO_N, PIPE_SIZE / 3, RC_OK}, {PIPE_SIZE / 3, _1_TO_N, PIPE_SIZE / 3, RC_OK}, {PIPE_SIZE / 3, _1_TO_N, PIPE_SIZE / 3, RC_OK}, {PIPE_SIZE / 3, _1_TO_N, 1, RC_OK}, {PIPE_SIZE / 3, _1_TO_N, 0, RC_FAIL} }; static SIZE_EXPECT zero_to_N[] = { {0, _0_TO_N, 0, RC_FAIL}, {1, _0_TO_N, 1, RC_OK}, {PIPE_SIZE - 1, _0_TO_N, PIPE_SIZE - 1, RC_OK}, {PIPE_SIZE, _0_TO_N, PIPE_SIZE, RC_OK}, {PIPE_SIZE + 1, _0_TO_N, PIPE_SIZE, RC_OK} }; static SIZE_EXPECT many_zero_to_N[] = { {PIPE_SIZE / 3, _0_TO_N, PIPE_SIZE / 3, RC_OK}, {PIPE_SIZE / 3, _0_TO_N, PIPE_SIZE / 3, RC_OK}, {PIPE_SIZE / 3, _0_TO_N, PIPE_SIZE / 3, RC_OK}, {PIPE_SIZE / 3, _0_TO_N, 1, RC_OK}, {PIPE_SIZE / 3, _0_TO_N, 0, RC_OK} }; /* * With the following 'wait' cases, the pipe buffer may be bypassed. It is * thus possible to transmit and receive via the pipe more bytes than its * buffer would allow. */ static SIZE_EXPECT wait_all_N[] = { {0, _ALL_N, 0, RC_FAIL}, {1, _ALL_N, 1, RC_OK}, {PIPE_SIZE - 1, _ALL_N, PIPE_SIZE - 1, RC_OK}, {PIPE_SIZE, _ALL_N, PIPE_SIZE, RC_OK}, {PIPE_SIZE + 1, _ALL_N, PIPE_SIZE + 1, RC_OK} }; static SIZE_EXPECT wait_one_to_N[] = { {0, _1_TO_N, 0, RC_FAIL}, {1, _1_TO_N, 1, RC_OK}, {PIPE_SIZE - 1, _1_TO_N, PIPE_SIZE - 1, RC_OK}, {PIPE_SIZE, _1_TO_N, PIPE_SIZE, RC_OK}, {PIPE_SIZE + 1, _1_TO_N, PIPE_SIZE + 1, RC_OK} }; static SIZE_EXPECT timeout_cases[] = { {0, _ALL_N, 0, RC_FAIL}, {1, _ALL_N, 0, RC_TIME}, {PIPE_SIZE - 1, _ALL_N, 0 , RC_TIME}, {PIPE_SIZE, _ALL_N, 0, RC_TIME}, {PIPE_SIZE + 1, _ALL_N, 0, RC_TIME}, {0, _1_TO_N, 0, RC_FAIL}, {1, _1_TO_N, 0, RC_TIME}, {PIPE_SIZE - 1, _1_TO_N, 0, RC_TIME}, {PIPE_SIZE, _1_TO_N, 0, RC_TIME}, {PIPE_SIZE + 1, _1_TO_N, 0, RC_TIME}, {0, _0_TO_N, 0, RC_FAIL}, {1, _0_TO_N, 0, RC_FAIL}, {PIPE_SIZE - 1, _0_TO_N, 0, RC_FAIL}, {PIPE_SIZE, _0_TO_N, 0, RC_FAIL}, {PIPE_SIZE + 1, _0_TO_N, 0, RC_FAIL} }; /* globals */ extern ksem_t regSem; extern ksem_t altSem; extern ksem_t counterSem; extern kpipe_t pipeId; /******************************************************************************* * * microObjectsInit - initialize objects used in this microkernel test suite * * RETURNS: N/A */ void microObjectsInit (void) { int i; /* loop counter */ for (i = 0; i < sizeof (rxBuffer); i++) { txBuffer[i] = (char) i; } } /******************************************************************************* * * receiveBufferCheck - check the contents of the receive buffer * * RETURNS: on success, index of wrong character on failure */ int receiveBufferCheck ( char * buffer, /* pointer to buffer to check */ int size /* number of bytes to check */ ) { int j; /* loop counter */ for (j = 0; j < size; j++) { if (buffer[j] != (char) j) { return j; } } return size; } /******************************************************************************* * * pipePutHelperWork - helper routine to pipePutTest() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipePutHelperWork ( SIZE_EXPECT * singleItems, /* testcase list (one item in the pipe) */ int nSingles, /* # of items in testcase */ SIZE_EXPECT * manyItems, /* testcase list (many items in the pipe) */ int nMany /* # of items in testcase */ ) { int i; /* loop counter */ int j; /* loop counter */ int rv; /* value returned from task_pipe_get() */ int index; /* index to corrupted byte in buffer */ int bytesReceived; /* number of bytes received */ for (i = 0; i < nSingles; i++) { (void)task_sem_take_wait (altSem); for (j = 0; j < sizeof (rxBuffer); j++) { rxBuffer[j] = 0; } rv = task_pipe_get (pipeId, rxBuffer, singleItems[i].size, &bytesReceived, singleItems[i].options); if (rv != singleItems[i].rcode) { TC_ERROR ("task_pipe_get(%d bytes) : Expected %d not %d.\n" " bytesReceived = %d\n", singleItems[i].size, singleItems[i].rcode, rv, bytesReceived); return TC_FAIL; } if (bytesReceived != singleItems[i].sent) { TC_ERROR ("task_pipe_get(%d) : " "Expected %d bytes to be received, not %d\n", singleItems[i].size, singleItems[i].sent, bytesReceived); return TC_FAIL; } index = receiveBufferCheck (rxBuffer, bytesReceived); if (index != bytesReceived) { TC_ERROR ("pipePutHelper: rxBuffer[%d] is %d, not %d\n", index, rxBuffer[index], index); return TC_FAIL; } task_sem_give (counterSem); task_sem_give (regSem); } /* * Get items from the pipe. There should be more than one item * stored in it. */ (void)task_sem_take_wait (altSem); for (i = 0; i < nMany; i++) { for (j = 0; j < sizeof (rxBuffer); j++) { rxBuffer[j] = 0; } rv = task_pipe_get (pipeId, rxBuffer, manyItems[i].size, &bytesReceived, manyItems[i].options); if (rv != manyItems[i].rcode) { TC_ERROR ("task_pipe_get(%d bytes) : Expected %d not %d.\n" " bytesReceived = %d, iteration: %d\n", manyItems[i].size, manyItems[i].rcode, rv, bytesReceived, i+1); return TC_FAIL; } if (bytesReceived != manyItems[i].sent) { TC_ERROR ("task_pipe_get(%d) : " "Expected %d bytes to be received, not %d\n", manyItems[i].size, manyItems[i].sent, bytesReceived); return TC_FAIL; } index = receiveBufferCheck (rxBuffer, bytesReceived); if (index != bytesReceived) { TC_ERROR ("pipeGetHelper: rxBuffer[%d] is %d, not %d\n", index, rxBuffer[index], index); return TC_FAIL; } task_sem_give (counterSem); } task_sem_give (regSem); /* Wake the RegressionTask */ return TC_PASS; } /******************************************************************************* * * pipePutHelper - helper routine to pipePutTest() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipePutHelper (void) { int rv; /* return value from pipePutHelperWork() */ rv = pipePutHelperWork (all_N, NELEMENTS(all_N), many_all_N, NELEMENTS(many_all_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on all_N/many_all_N test\n"); return TC_FAIL; } rv = pipePutHelperWork (one_to_N, NELEMENTS(one_to_N), many_one_to_N, NELEMENTS(many_one_to_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _1_TO_N/many_1_TO_N test\n"); return TC_FAIL; } rv = pipePutHelperWork (zero_to_N, NELEMENTS(zero_to_N), many_zero_to_N, NELEMENTS(many_zero_to_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _0_TO_N/many_0_TO_N test\n"); return TC_FAIL; } return TC_PASS; } /******************************************************************************* * * pipePutTestWork - test task_pipe_put() * * This routine tests the task_pipe_put() API. * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipePutTestWork ( SIZE_EXPECT * singleItems, /* testcase list (one item in the pipe) */ int nSingles, /* # of items in testcase */ SIZE_EXPECT * manyItems, /* testcase list (many items in the pipe) */ int nMany /* # of items in testcase */ ) { int rv; /* return code from task_pipe_put() */ int i; /* loop counter */ int bytesWritten; /* # of bytes sent to pipe */ int nitem; /* expected item number processed by the other task */ task_sem_reset (counterSem); for (i = 0; i < nSingles; i++) { rv = task_pipe_put (pipeId, txBuffer, singleItems[i].size, &bytesWritten, singleItems[i].options); if (rv != singleItems[i].rcode) { TC_ERROR ("task_pipe_put(%d) : Expected %d not %d.\n" " bytesWritten = %d, Iteration: %d\n", singleItems[i].size, singleItems[i].rcode, rv, bytesWritten, i + 1); return TC_FAIL; } if (bytesWritten != singleItems[i].sent) { TC_ERROR ("task_pipe_put(%d) : " "Expected %d bytes to be written, not %d\n", singleItems[i].size, singleItems[i].sent, bytesWritten); return TC_FAIL; } task_sem_give (altSem); (void)task_sem_take_wait (regSem); nitem = task_sem_count_get (counterSem) - 1; if (nitem != i) { TC_ERROR ("Expected item number is %d, not %d\n", i, nitem); return TC_FAIL; } } /* This time, more than one item will be in the pipe at a time */ task_sem_reset (counterSem); for (i = 0; i < nMany; i++) { rv = task_pipe_put (pipeId, txBuffer, manyItems[i].size, &bytesWritten, manyItems[i].options); if (rv != manyItems[i].rcode) { TC_ERROR ("task_pipe_put(%d) : Expected %d not %d.\n" " bytesWritten = %d, iteration: %d\n", manyItems[i].size, manyItems[i].rcode, rv, bytesWritten, i + 1); return TC_FAIL; } if (bytesWritten != manyItems[i].sent) { TC_ERROR ("task_pipe_put(%d) : " "Expected %d bytes to be written, not %d\n", manyItems[i].size, manyItems[i].sent, bytesWritten); return TC_FAIL; } } task_sem_give (altSem); /* Wake the alternate task */ /* wait for other task reading all the items from pipe */ (void)task_sem_take_wait (regSem); if (task_sem_count_get (counterSem) != nMany) { TC_ERROR ("Expected number of items %d, not %d\n", nMany, task_sem_count_get (counterSem)); return TC_FAIL; } return TC_PASS; } /******************************************************************************* * * pipePutTest - test task_pipe_put() * * This routine tests the task_pipe_put() API. * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipePutTest (void) { int rv; /* return value from pipePutTestWork() */ rv = pipePutTestWork (all_N, NELEMENTS(all_N), many_all_N, NELEMENTS(many_all_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _ALL_N/many_ALL_N test\n"); return TC_FAIL; } rv = pipePutTestWork (one_to_N, NELEMENTS(one_to_N), many_one_to_N, NELEMENTS(many_one_to_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _1_TO_N/many_1_TO_N test\n"); return TC_FAIL; } rv = pipePutTestWork (zero_to_N, NELEMENTS(zero_to_N), many_zero_to_N, NELEMENTS(many_zero_to_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _0_TO_N/many_0_TO_N test\n"); return TC_FAIL; } return TC_PASS; } /******************************************************************************* * * pipePutWaitHelper - help test task_pipe_put_wait() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipePutWaitHelper (void) { int i; /* loop counter */ int rv; /* return value from task_pipe_get_wait */ int bytesRead; /* # of bytes read from task_pipe_get_wait() */ (void)task_sem_take_wait (altSem); /* Wait until test is ready */ /* 1. task_pipe_get_wait() will force a context switch to RegressionTask() */ rv = task_pipe_get_wait (pipeId, rxBuffer, PIPE_SIZE, &bytesRead, _ALL_N); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE)) { TC_ERROR ("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE, bytesRead); return TC_FAIL; } /* 2. task_pipe_get_wait() will force a context switch to RegressionTask(). */ rv = task_pipe_get_wait (pipeId, rxBuffer, PIPE_SIZE, &bytesRead, _1_TO_N); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE)) { TC_ERROR ("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE, bytesRead); return TC_FAIL; } /* * Before emptying the pipe, check that task_pipe_get_wait() fails when * using the _0_TO_N option. */ rv = task_pipe_get_wait (pipeId, rxBuffer, PIPE_SIZE / 2, &bytesRead, _0_TO_N); if (rv != RC_FAIL) { TC_ERROR ("Expected return code %d, not %d\n", RC_FAIL, rv); return TC_FAIL; } /* 3. Empty the pipe in two reads */ for (i = 0; i < 2; i++) { rv = task_pipe_get (pipeId, rxBuffer, PIPE_SIZE / 2, &bytesRead, _0_TO_N); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE / 2)) { TC_ERROR ("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE / 2, bytesRead); return TC_FAIL; } } task_sem_give (regSem); return TC_PASS; } /******************************************************************************* * * pipePutWaitTest - test task_pipe_put_wait() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipePutWaitTest (void) { int rv; /* return code from task_pipe_put_wait() */ int bytesWritten; /* # of bytes written to pipe */ /* 1. Fill the pipe */ rv = task_pipe_put_wait (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _ALL_N); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } task_sem_give (altSem); /* Wake the alternate task */ /* 2. task_pipe_put_wait() will force a context switch to AlternateTask(). */ rv = task_pipe_put_wait (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _ALL_N); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } /* 3. task_pipe_put_wait() will force a context switch to AlternateTask(). */ rv = task_pipe_put_wait (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _1_TO_N); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } /* This should return immediately as _0_TO_N with a wait is an error. */ rv = task_pipe_put_wait (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _0_TO_N); if ((rv != RC_FAIL) || (bytesWritten != 0)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_FAIL, rv, 0, bytesWritten); return TC_FAIL; } /* Wait for AlternateTask()'s pipePutWaitHelper() to finish */ (void)task_sem_take_wait (regSem); return TC_PASS; } /******************************************************************************* * * pipePutTimeoutHelper - test task_pipe_get_wait_timeout() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipePutTimeoutHelper (void) { int i; /* loop counter */ int rv; /* return value from task_pipe_get_wait_timeout() */ int bytesRead; /* # of bytes read from task_pipe_get_wait_timeout() */ (void)task_sem_take_wait (altSem); /* Wait until test is ready */ /* 1. task_pipe_get_wait_timeout() will force a context switch to RegressionTask() */ rv = task_pipe_get_wait_timeout (pipeId, rxBuffer, PIPE_SIZE, &bytesRead, _ALL_N, ONE_SECOND); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE)) { TC_ERROR ("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE, bytesRead); return TC_FAIL; } /* 2. task_pipe_get_wait_timeout() will force a context switch to RegressionTask(). */ rv = task_pipe_get_wait_timeout (pipeId, rxBuffer, PIPE_SIZE, &bytesRead, _1_TO_N, ONE_SECOND); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE)) { TC_ERROR ("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE, bytesRead); return TC_FAIL; } /* * Before emptying the pipe, check that task_pipe_get_wait_timeout() fails when * using the _0_TO_N option. */ rv = task_pipe_get_wait_timeout (pipeId, rxBuffer, PIPE_SIZE / 2, &bytesRead, _0_TO_N, ONE_SECOND); if (rv != RC_FAIL) { TC_ERROR ("Expected return code %d, not %d\n", RC_FAIL, rv); return TC_FAIL; } /* 3. Empty the pipe in two reads */ for (i = 0; i < 2; i++) { rv = task_pipe_get (pipeId, rxBuffer, PIPE_SIZE / 2, &bytesRead, _0_TO_N); if ((rv != RC_OK) || (bytesRead != PIPE_SIZE / 2)) { TC_ERROR ("Expected return code %d, not %d\n" "Expected %d bytes to be read, not %d\n", RC_OK, rv, PIPE_SIZE / 2, bytesRead); return TC_FAIL; } } task_sem_give (regSem); return TC_PASS; } /******************************************************************************* * * pipePutTimeoutTest - test task_pipe_put_wait_timeout() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipePutTimeoutTest (void) { int rv; /* return code from task_pipe_put_wait_timeout() */ int bytesWritten; /* # of bytes written to task_pipe_put_wait_timeout() */ /* 1. Fill the pipe */ rv = task_pipe_put_wait_timeout (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _ALL_N, ONE_SECOND); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } /* Timeout while waiting to put data into the pipe */ rv = task_pipe_put_wait_timeout (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _ALL_N, ONE_SECOND); if ((rv != RC_TIME) || (bytesWritten != 0)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_TIME, rv, 0, bytesWritten); return TC_FAIL; } rv = task_pipe_put_wait_timeout (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _1_TO_N, ONE_SECOND); if ((rv != RC_TIME) || (bytesWritten != 0)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_TIME, rv, 0, bytesWritten); return TC_FAIL; } task_sem_give (altSem); /* Wake the alternate task */ /* 2. task_pipe_put_wait() will force a context switch to AlternateTask(). */ rv = task_pipe_put_wait_timeout (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _ALL_N, ONE_SECOND); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } /* 3. task_pipe_put_wait() will force a context switch to AlternateTask(). */ rv = task_pipe_put_wait_timeout (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _1_TO_N, ONE_SECOND); if ((rv != RC_OK) || (bytesWritten != PIPE_SIZE)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_OK, rv, PIPE_SIZE, bytesWritten); return TC_FAIL; } /* This should return immediately as _0_TO_N with a wait is an error. */ rv = task_pipe_put_wait (pipeId, txBuffer, PIPE_SIZE, &bytesWritten, _0_TO_N); if ((rv != RC_FAIL) || (bytesWritten != 0)) { TC_ERROR ("Return code: expected %d, got %d\n" "Bytes written: expected %d, got %d\n", RC_FAIL, rv, 0, bytesWritten); return TC_FAIL; } /* Wait for AlternateTask()'s pipePutWaitHelper() to finish */ (void)task_sem_take_wait (regSem); return TC_PASS; } /******************************************************************************* * * pipeGetTest - routine to test task_pipe_get() * * This routine tests the task_pipe_get() API. Some of this functionality * has already been tested while testing task_pipe_put(). As a result, the * only remaining functionality that needs to be checked are attempts to get * data from an empty pipe. * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipeGetTest (void) { int i; /* loop counter */ int j; /* loop counter */ int rv; /* return code from task_pipe_get() */ int bytesRead; /* # of bytes read from task_pipe_get() */ int size[] ={1, PIPE_SIZE - 1, PIPE_SIZE, PIPE_SIZE + 1}; K_PIPE_OPTION options[] = {_ALL_N, _1_TO_N}; for (j = 0; j < NELEMENTS(options); j++) { for (i = 0; i < NELEMENTS(size); i++) { rv = task_pipe_get (pipeId, rxBuffer, size[i], &bytesRead, options[j]); if (rv != RC_FAIL) { TC_ERROR ("Expected return code %d, not %d\n", RC_FAIL, rv); return TC_FAIL; } } } for (i = 0; i < NELEMENTS(size); i++) { rv = task_pipe_get (pipeId, rxBuffer, size[i], &bytesRead, _0_TO_N); if (rv != RC_OK) { TC_ERROR ("Expected return code %d, not %d\n", RC_OK, rv); return TC_FAIL; } if (bytesRead != 0) { TC_ERROR ("Expected %d, not %d\n", 0, bytesRead); return TC_FAIL; } } return TC_PASS; } /******************************************************************************* * * pipeGetWaitHelperWork - test task_pipe_get_wait() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipeGetWaitHelperWork ( SIZE_EXPECT * items, /* testcase list for task_pipe_get_wait() */ int nItems /* # of items in list */ ) { int i; /* loop counter */ int rv; /* return value from task_pipe_put_wait() */ int bytesSent; /* # of bytes sent to task_pipe_put_wait() */ for (i = 0; i < nItems; i++) { /* * Pipe should be empty. Most calls to task_pipe_get_wait() should * block until the call to task_pipe_put() is performed in the routine * pipeGetWaitHelperWork(). */ bytesSent = 0; rv = task_pipe_put_wait (pipeId, rxBuffer, items[i].size, &bytesSent, items[i].options); if ((rv != items[i].rcode) || (bytesSent != items[i].sent)) { TC_ERROR ("Expected return value %d, got %d\n" "Expected bytesSent = %d, got %d\n", items[i].rcode, rv, 0, bytesSent); return TC_FAIL; } } return TC_PASS; } /******************************************************************************* * * pipeGetWaitHelper - test task_pipe_get_wait() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipeGetWaitHelper (void) { int rv; /* return coded form pipeGetWaitHelperWork() */ (void)task_sem_take_wait (altSem); rv = pipeGetWaitHelperWork (wait_all_N, NELEMENTS(wait_all_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _ALL_N test\n"); return TC_FAIL; } rv = pipeGetWaitHelperWork (wait_one_to_N, NELEMENTS(wait_one_to_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _1_TO_N test\n"); return TC_FAIL; } return TC_PASS; } /******************************************************************************* * * pipeGetWaitTestWork - test task_pipe_get_wait() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipeGetWaitTestWork ( SIZE_EXPECT * items, /* testcase list for task_pipe_get_wait() */ int nItems /* # of items in list */ ) { int i; /* loop counter */ int rv; /* return code from task_pipe_get_wait() */ int bytesRead; /* # of bytes read from task_pipe_get_wait() */ for (i = 0; i < nItems; i++) { /* * Pipe should be empty. Most calls to task_pipe_get_wait() should * block until the call to task_pipe_put() is performed in the routine * pipeGetWaitHelperWork(). */ rv = task_pipe_get_wait (pipeId, rxBuffer, items[i].size, &bytesRead, items[i].options); if ((rv != items[i].rcode) || (bytesRead != items[i].sent)) { TC_ERROR ("Expected return value %d, got %d\n" "Expected bytesRead = %d, got %d\n", items[i].rcode, rv, 0, bytesRead); return TC_FAIL; } } return TC_PASS; } /******************************************************************************* * * pipeGetWaitTest - test task_pipe_get_wait() * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipeGetWaitTest (void) { int rv; /* return code from pipeGetWaitTestWork() */ int bytesRead; /* # of bytes read from task_pipe_get_waitait() */ task_sem_give (altSem); /* Wake AlternateTask */ rv = pipeGetWaitTestWork (wait_all_N, NELEMENTS(wait_all_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _ALL_N test\n"); return TC_FAIL; } rv = pipeGetWaitTestWork (wait_one_to_N, NELEMENTS(wait_one_to_N)); if (rv != TC_PASS) { TC_ERROR ("Failed on _1_TO_N test\n"); return TC_FAIL; } rv = task_pipe_get_wait (pipeId, rxBuffer, PIPE_SIZE, &bytesRead, _0_TO_N); if (rv != RC_FAIL) { TC_ERROR ("Expected return code of %d, not %d\n", RC_FAIL, rv); return TC_FAIL; } return TC_PASS; } /******************************************************************************* * * pipeGetTimeoutTest - test remaining task_pipe_get_wait_timeout() functionality * * RETURNS: TC_PASS on success, TC_FAIL on failure */ int pipeGetTimeoutTest (void) { int i; /* loop counter */ int rv; /* return value from task_pipe_get_wait_timeout() */ int bytesRead; /* # of bytes read from task_pipe_get_wait_timeout() */ for (i = 0; i < NELEMENTS(timeout_cases); i++) { rv = task_pipe_get_wait_timeout (pipeId, rxBuffer, timeout_cases[i].size, &bytesRead, timeout_cases[i].options, ONE_SECOND); if ((rv != timeout_cases[i].rcode) || (bytesRead != timeout_cases[i].sent)) { TC_ERROR ("Expected return code %d, got %d\n" "Expected %d, got %d\n" "Iteration %d\n", timeout_cases[i].rcode, rv, timeout_cases[i].sent, bytesRead, i + 1); return TC_FAIL; } } return TC_PASS; } /******************************************************************************* * * AlternateTask - alternate task in the test suite * * This routine runs at a lower priority than RegressionTask(). * * RETURNS: TC_PASS or TC_FAIL */ int AlternateTask (void) { int rv; /* return code from each set of test cases */ rv = pipePutHelper (); if (rv != TC_PASS) { return TC_FAIL; } rv = pipePutWaitHelper (); if (rv != TC_PASS) { return TC_FAIL; } rv = pipePutTimeoutHelper (); if (rv != TC_PASS) { return TC_FAIL; } /* * There is no pipeGetHelper() as the task_pipe_get() checks have * either been done in pipePutHelper(), or pipeGetTest(). */ rv = pipeGetWaitHelper (); if (rv != TC_PASS) { return TC_FAIL; } /* * There is no pipeGetTimeoutHelper() as the task_pipe_get_wait_timeout() checks * have either been done in pipePutTimeoutHelper() or * pipeGetTimeoutTest(). */ return TC_PASS; } /******************************************************************************* * * RegressionTask - main task in the test suite * * This is the entry point to the VxMicro target pipe test suite. * * RETURNS: TC_PASS or TC_FAIL */ int RegressionTask (void) { int tcRC; /* test case return code */ microObjectsInit (); TC_PRINT ("Testing task_pipe_put() ...\n"); tcRC = pipePutTest (); if (tcRC != TC_PASS) { return TC_FAIL; } TC_PRINT ("Testing task_pipe_put_wait() ...\n"); tcRC = pipePutWaitTest (); if (tcRC != TC_PASS) { return TC_FAIL; } TC_PRINT ("Testing task_pipe_put_wait_timeout() ...\n"); tcRC = pipePutTimeoutTest (); if (tcRC != TC_PASS) { return TC_FAIL; } TC_PRINT ("Testing task_pipe_get() ...\n"); tcRC = pipeGetTest (); if (tcRC != TC_PASS) { return TC_FAIL; } TC_PRINT ("Testing task_pipe_get_wait() ...\n"); tcRC = pipeGetWaitTest (); if (tcRC != TC_PASS) { return TC_FAIL; } TC_PRINT ("Testing task_pipe_get_wait_timeout() ...\n"); tcRC = pipeGetTimeoutTest (); if (tcRC != TC_PASS) { return TC_FAIL; } return TC_PASS; }