diff options
Diffstat (limited to 'src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.cpp')
-rw-r--r-- | src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.cpp b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.cpp new file mode 100644 index 0000000000..f294cea472 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.cpp @@ -0,0 +1,235 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Source: criticalsectionfunctions/test1/initializecriticalsection.c +** +** Purpose: Test Semaphore operation using classic IPC problem: +** "Producer-Consumer Problem". +** +** Dependencies: CreateThread +** InitializeCriticalSection +** EnterCriticalSection +** LeaveCriticalSection +** DeleteCriticalSection +** WaitForSingleObject +** Sleep +** + +** +**=========================================================*/ + +#include <palsuite.h> + +#define PRODUCTION_TOTAL 26 + +#define _BUF_SIZE 10 + +DWORD dwThreadId; /* consumer thread identifier */ + +HANDLE hThread; /* handle to consumer thread */ + +CRITICAL_SECTION CriticalSectionM; /* Critical Section Object (used as mutex) */ + +typedef struct Buffer +{ + short readIndex; + short writeIndex; + CHAR message[_BUF_SIZE]; + +} BufferStructure; + +CHAR producerItems[PRODUCTION_TOTAL + 1]; + +CHAR consumerItems[PRODUCTION_TOTAL + 1]; + +/* + * Read next message from the Buffer into provided pointer. + * Returns: 0 on failure, 1 on success. + */ +int +readBuf(BufferStructure *Buffer, char *c) +{ + if( Buffer -> writeIndex == Buffer -> readIndex ) + { + return 0; + } + *c = Buffer -> message[Buffer -> readIndex++]; + Buffer -> readIndex %= _BUF_SIZE; + return 1; +} + +/* + * Write message generated by the producer to Buffer. + * Returns: 0 on failure, 1 on success. + */ +int +writeBuf(BufferStructure *Buffer, CHAR c) +{ + if( ( ((Buffer -> writeIndex) + 1) % _BUF_SIZE) == + (Buffer -> readIndex) ) + { + return 0; + } + Buffer -> message[Buffer -> writeIndex++] = c; + Buffer -> writeIndex %= _BUF_SIZE; + return 1; +} + +/* + * Sleep 500 milleseconds. + */ +VOID +consumerSleep(VOID) +{ + Sleep(500); +} + +/* + * Sleep between 10 milleseconds. + */ +VOID +producerSleep(VOID) +{ + Sleep(10); +} + +/* + * Produce a message and write the message to Buffer. + */ +VOID +producer(BufferStructure *Buffer) +{ + + int n = 0; + char c; + + while (n < PRODUCTION_TOTAL) + { + c = 'A' + n ; /* Produce Item */ + + EnterCriticalSection(&CriticalSectionM); + + if (writeBuf(Buffer, c)) + { + printf("Producer produces %c.\n", c); + producerItems[n++] = c; + } + + LeaveCriticalSection(&CriticalSectionM); + + producerSleep(); + } + + return; +} + +/* + * Read and "Consume" the messages in Buffer. + */ +DWORD +PALAPI +consumer( LPVOID lpParam ) +{ + int n = 0; + char c; + + consumerSleep(); + + while (n < PRODUCTION_TOTAL) + { + + EnterCriticalSection(&CriticalSectionM); + + if (readBuf((BufferStructure*)lpParam, &c)) + { + printf("\tConsumer consumes %c.\n", c); + consumerItems[n++] = c; + } + + LeaveCriticalSection(&CriticalSectionM); + + consumerSleep(); + } + + return 0; +} + +int __cdecl main (int argc, char **argv) +{ + + BufferStructure Buffer, *pBuffer; + + pBuffer = &Buffer; + + if(0 != (PAL_Initialize(argc, argv))) + { + return FAIL; + } + + /* + * Create mutual exclusion mechanisms + */ + + InitializeCriticalSection ( &CriticalSectionM ); + + /* + * Initialize Buffer + */ + pBuffer->writeIndex = pBuffer->readIndex = 0; + + + + /* + * Create Consumer + */ + hThread = CreateThread( + NULL, + 0, + consumer, + &Buffer, + 0, + &dwThreadId); + + if ( NULL == hThread ) + { + Fail ( "CreateThread() returned NULL. Failing test.\n" + "GetLastError returned %d\n", GetLastError()); + } + + /* + * Start producing + */ + producer(pBuffer); + + /* + * Wait for consumer to complete + */ + WaitForSingleObject (hThread, INFINITE); + + /* + * Compare items produced vs. items consumed + */ + if ( 0 != strncmp (producerItems, consumerItems, PRODUCTION_TOTAL) ) + { + Fail("The producerItems string %s\n and the consumerItems string " + "%s\ndo not match. This could be a problem with the strncmp()" + " function\n FailingTest\nGetLastError() returned %d\n", + producerItems, consumerItems, GetLastError()); + } + + /* + * Clean up Critical Section object + */ + DeleteCriticalSection(&CriticalSectionM); + + Trace("producerItems and consumerItems arrays match. All %d\nitems " + "were produced and consumed in order.\nTest passed.\n", + PRODUCTION_TOTAL); + + PAL_Terminate(); + return (PASS); + +} |