📄 thread.c
字号:
Result = TEST_FAILED; } } return (Result);}/******************************************************************************Function Name : CleanUpDisk Description : Helper for SameFile: close and delete the shared file, then terminate the partition Parameters :******************************************************************************/static TestResult_t CleanUpDisk(void){ TestResult_t Result = TEST_PASSED; if (ST_NO_ERROR != STAVFS_CloseFile (SharedFileHandle)) { STTBX_Print (("Error closing shared file\n")); Result = TEST_FAILED; } if (ST_NO_ERROR != STAVFS_DeleteFile (SharedDiskHandle, STAVFS_NULL_FILE_HANDLE, FILE_NAME)) { STTBX_Print (("Error deleting shared file\n")); Result = TEST_FAILED; } if (TEST_PASSED != ClosePartition (DEV_NAME, SharedDiskHandle)) { Result = TEST_FAILED; /* message already displayed */ } return (Result);}/******************************************************************************Function Name : LaunchWriters Description : Helper for SameFile: set up and launch the writer threads Parameters : ******************************************************************************/static TestResult_t LaunchWriters(void){ TestResult_t Result = TEST_PASSED; char * WriterNames[NUM_WRITERS] = { "Writer 1", "Writer 2" }; int i, PatternIdx; /* Give all writer tasks the same priority as ourselves */ int Priority = task_priority(NULL); /* set up the thread co-ordination flags */ Finished = FALSE; HadError = FALSE; /* Set up the writer threads and their input */ for (i = 0; (i < NUM_WRITERS); ++i) { PatternIdx = (i % NUM_PATTERNS); WriterData[i].Pattern_p = Patterns[PatternIdx]; WriterData[i].ChunkSize = ChunkSizes[PatternIdx]; WriterData[i].ChunksWritten = 0; WriterThreads[i] = task_create (WriterThreadProc, /* thread procedure */ (void *) &(WriterData[i]), /* param */ 4 * K_BYTES, /* stack size */ Priority, /* priority */ WriterNames[i], /* debugger name */ task_flags_suspended); /* flags */ if (WriterThreads[i] == NULL) { STTBX_Print (("Failed to create writer thread %i" " for thread-safety test\n", i)); Result = TEST_FAILED; break; } } /* -> i-1: last writer successfully created (-1 for none) */ /* Start them off as close as possible together; in error case we still need to do this, but they will run to completion very quickly */ while (--i >= 0) { task_resume (WriterThreads[i]); if (Result == TEST_FAILED) { task_wait (&(WriterThreads[i]), 1, TIMEOUT_INFINITY); task_delete (WriterThreads[i]); } } return (Result);}/******************************************************************************Function Name : WriterThreadProc Description : Thread procedure that writes up to MAX_CHUNKS of the indicated size and pattern Parameters :******************************************************************************/static void WriterThreadProc(void * Param){ WriterData_t * WriterData_p = (WriterData_t *) Param; ST_ErrorCode_t Error; U32 BytesWritten; /* Write chunks until us or another writer hit the limit, or an error occurs */ while (!Finished && !HadError) { Error = STAVFS_WriteFile (SharedFileHandle, WriterData_p->Pattern_p, WriterData_p->ChunkSize, &BytesWritten); if (Error != ST_NO_ERROR) { STTBX_Print (("%s: Error 0x%08X writing chunk %u", task_name(NULL), Error, WriterData_p->ChunksWritten + 1)); HadError = TRUE; /* give up */ } else { ++WriterData_p->ChunksWritten; if (WriterData_p->ChunksWritten == MAX_CHUNKS) { /* signal us and other writer threads to stop */ Finished = TRUE; } } } }/******************************************************************************Function Name : ReadChunks Description : Helper for SameFile: read in chunks as fast as we can get them, confirming that they are Pattern1 or Pattern2, not some corrupted mess. Keep going until writer threads terminate Parameters :******************************************************************************/static TestResult_t ReadChunks(void){ TestResult_t Result = TEST_PASSED; ST_ErrorCode_t Error; U32 BytesRead, RemainderBytes; U32 ChunksRead = 0; /* check the total count */ /* flag around waiting for writers to completely finish */ BOOL ThreadsComplete = FALSE; int i; while (1) /* exit via breaks below */ { /* For simplicity, once one writer has finished, we wait for them all to complete their final write before reading them in */ if (Finished || HadError) { for (i = 0; (i < NUM_WRITERS); ++i) { task_wait (WriterThreads+i, 1, TIMEOUT_INFINITY); } ThreadsComplete = TRUE; /* exit once read to EOF */ } if (HadError) { break; /* give up now threads are finished */ } /* read the amount of data we will always have to read, and use it to identify which pattern we are on */ Error = STAVFS_ReadFile (SharedFileHandle, Buffer, MIN_CHUNK_SIZE, &BytesRead); if ((Error == STAVFS_ERROR_EOF) && (BytesRead == 0)) { if (ThreadsComplete) { /* read to EOF after all writers have finished - we're done */ break; } /* otherwise wait for more data to appear */ } else if (Error != ST_NO_ERROR) { STTBX_Print (("Error reading start of chunk %u\n", ChunksRead + 1)); HadError = TRUE; /* terminate threads then exit loop */ } else { for (i = 0; (i < NUM_PATTERNS); ++i) { if (0 == memcmp (Buffer, Patterns[i], MIN_CHUNK_SIZE)) { break; /* match */ } } if (i == NUM_PATTERNS) { STTBX_Print (("Start of chunk %u doesn't fit any of the patterns\n", ChunksRead + 1)); HadError = TRUE; /* terminate threads then exit loop */ } else { /* read and check the remainder of the pattern. They're written in a single write operation, so having got the start, we should be able to get the end without EOF */ RemainderBytes = ChunkSizes[i] - MIN_CHUNK_SIZE; if (ST_NO_ERROR != STAVFS_ReadFile (SharedFileHandle, Buffer, RemainderBytes, &BytesRead)) { STTBX_Print (("Error reading remainder of chunk %u\n", ChunksRead + 1)); HadError = TRUE; /* terminate threads then exit loop */ } else if (memcmp (Buffer, Patterns[i] + MIN_CHUNK_SIZE, RemainderBytes)) { STTBX_Print (("Remainder of chunk %u doesn't match" " pattern %i identified from its start\n", ChunksRead + 1, i)); HadError = TRUE; /* terminate threads then exit loop */ } else { ++ChunksRead; } } } } /* check final state in non-error case */ if (HadError || (TEST_PASSED != CheckFinalState (ChunksRead))) { /* propogate the fact that the test has failed */ Result = TEST_FAILED; } /* clean up threads - we could actually use this (checking for failure) in place of task_wait above */ for (i = 0; i < NUM_WRITERS; ++i) { task_delete (WriterThreads[i]); } return (Result);}/******************************************************************************Function Name : CheckFinalState Description : Helper for ReadChunks: check the writer chunk counts against the total read, and check no writer was given undue priority Parameters :******************************************************************************/static TestResult_t CheckFinalState(U32 TotalRead){ TestResult_t Result = TEST_PASSED; U32 TotalWritten = 0; U32 LowerBound, UpperBound; int i; for (i = 0; i < NUM_WRITERS; ++i) { TotalWritten += WriterData[i].ChunksWritten; } if (TotalWritten != TotalRead) { STTBX_Print (("Not all the chunks written (%u) were read back (%u)\n", TotalWritten, TotalRead)); Result = TEST_FAILED; } else { /* Require that no writer gets more than 20% above or below the average amount of action */ LowerBound = (TotalWritten * 4) / (NUM_WRITERS * 5); UpperBound = (TotalWritten * 6) / (NUM_WRITERS * 5); for (i = 0; i < NUM_WRITERS; ++i) { if ((WriterData[i].ChunksWritten < LowerBound) || (WriterData[i].ChunksWritten > UpperBound)) { STTBX_Print (("Writers did not get uniform usage of the disk\n")); Result = TEST_FAILED; break; } } } return (Result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -