// ------------------------------------------------------------------------------------------------- void prio_Start ( void ) // ------------------------------------------------------------------------------------------------- { // Note, we actually don't need to increment and decrement the memory block reference count // because we don't return until the test is complete. #if LE_CONFIG_LINUX le_thread_Ref_t idleThread = le_thread_Create("idle", ThreadMainFunction, (void*)SCHED_IDLE); #endif #if LE_CONFIG_THREAD_REALTIME_ONLY const ssize_t expectedSched = SCHED_RR; #else const ssize_t expectedSched = SCHED_OTHER; #endif le_thread_Ref_t normalThread = le_thread_Create("norm", ThreadMainFunction, (void*)expectedSched); #if LE_CONFIG_LINUX le_thread_SetJoinable(idleThread); #endif le_thread_SetJoinable(normalThread); #if LE_CONFIG_LINUX LE_ASSERT(LE_OK == le_thread_SetPriority(idleThread, LE_THREAD_PRIORITY_IDLE)); #endif LE_ASSERT(LE_OK == le_thread_SetPriority(normalThread, LE_THREAD_PRIORITY_NORMAL)); #if LE_CONFIG_LINUX le_thread_Start(idleThread); #endif le_thread_Start(normalThread); void* unused; LE_ASSERT(LE_OK == le_thread_Join(normalThread, &unused)); #if LE_CONFIG_LINUX LE_ASSERT(LE_OK == le_thread_Join(idleThread, &unused)); #endif }
//-------------------------------------------------------------------------------------------------- static void TryConnect ( ConnectServiceFunc_t connectFuncPtr, ///< Function to call to connect to service char* serviceNamePtr ///< String containing name of the service ) { // Print out message before trying to connect to service to give user some kind of feedback printf("Connecting to service ...\n"); fflush(stdout); // Use a separate thread for recovery. It will be stopped once connected to the service. // Make the thread joinable, so we can be sure the thread is stopped before continuing. le_thread_Ref_t threadRef = le_thread_Create("timout thread", TimeoutThread, serviceNamePtr); le_thread_SetJoinable(threadRef); le_thread_Start(threadRef); // Try connecting to the service connectFuncPtr(); // Connected to the service, so stop the timeout thread le_thread_Cancel(threadRef); le_thread_Join(threadRef, NULL); }
void launch_thread() { int i; le_thread_Ref_t thread[NB_THREADS]; GSemPtr = le_sem_Create( SEM_NAME_1, 5); GSem2Ptr = le_sem_Create( SEM_NAME_2, 2); CU_ASSERT_PTR_NOT_EQUAL(GSemPtr, NULL); for (i = 0; i < NB_THREADS; i ++) { char threadName[20]; snprintf(threadName,20,"Thread_%d",i); thread[i] = le_thread_Create(threadName, fonction_thread, NULL); le_thread_SetJoinable(thread[i]); le_thread_Start(thread[i]); usleep(10000); } for (i = 0; i < NB_THREADS; i ++) { le_thread_Join(thread[i], NULL); } le_sem_Delete(GSem2Ptr); le_sem_Delete(GSemPtr); CU_PASS("GlobalSemaphore destroy"); }
// ------------------------------------------------------------------------------------------------- static void SpawnChildren ( size_t depth, // Indicates what nesting level the thread is at. // 1 = children of the process main thread. void* completionObjPtr // Ptr to the object whose ref count is used to terminate the test. ) // ------------------------------------------------------------------------------------------------- { int i; char childName[32]; le_thread_Ref_t children[FAN_OUT]; // Create and start all the children. for (i = 0; i < FAN_OUT; i++) { le_thread_Ref_t threadRef; Context_t* contextPtr = le_mem_ForceAlloc(ContextPoolRef); contextPtr->depth = depth; contextPtr->completionObjPtr = completionObjPtr; le_mem_AddRef(completionObjPtr); snprintf(childName, sizeof(childName), "%s-%d", le_thread_GetMyName(), i + 1); LE_INFO("Spawning thread '%s'.", childName); threadRef = le_thread_Create(childName, ThreadMainFunction, contextPtr); LE_INFO("Thread '%s' created.", childName); // Create a thread destructor that will release the Context object and the // Test Completion Object that we are going to pass to the child. le_thread_AddChildDestructor(threadRef, ThreadDestructor, contextPtr); LE_INFO("Thread '%s' destructor added.", childName); // Make every third child thread non-joinable and the rest joinable. if (((i + 1) % 3) != 0) { le_thread_SetJoinable(threadRef); } LE_INFO("Thread '%s' joinability set.", childName); // Start the child thread. le_thread_Start(threadRef); LE_INFO("Thread '%s' started.", childName); // Remember the child's thread reference for later join attempt. children[i] = threadRef; } // Join with all the children. for (i = 0; i < FAN_OUT; i++) { void* threadReturnValue; snprintf(childName, sizeof(childName), "%s-%d", le_thread_GetMyName(), i + 1); LE_INFO("Joining with thread '%s'.", childName); le_result_t result = le_thread_Join(children[i], &threadReturnValue); if (result != LE_OK) { LE_INFO("Failed to join with thread '%s'.", childName); LE_FATAL_IF(((i + 1) % 3) != 0, "Failed to join with joinable thread '%s'!", childName); } else { LE_INFO("Successfully joined with thread '%s', which returned %p.", childName, threadReturnValue); LE_FATAL_IF(((i + 1) % 3) == 0, "Joined with non-joinable thread '%s'!", childName); LE_FATAL_IF(threadReturnValue != completionObjPtr, "Thread returned strange value %p. Expected %p.", threadReturnValue, completionObjPtr); } } }
// ------------------------------------------------------------------------------------------------- static void SpawnChildren ( size_t depth // Indicates what nesting level the thread is at. // 1 = children of the process main thread. ) // ------------------------------------------------------------------------------------------------- { int i, j, k; char childName[32]; le_thread_Ref_t children[FAN_OUT]; const char* threadName = le_thread_GetMyName(); if (depth == 2) { LE_ASSERT(sscanf(threadName, "%*[^-]-%d", &j) == 1); // switch to zero-based j--; LE_TEST_INFO("depth 2: j=%d", j); } else if (depth == 3) { LE_ASSERT(sscanf(threadName, "%*[^-]-%d-%d", &k, &j) == 2); // switch to zero based k--; j--; LE_TEST_INFO("depth 3: j=%d,k=%d", j, k); } // Create and start all the children. for (i = 0; i < FAN_OUT; i++) { le_thread_Ref_t threadRef; Context_t* contextPtr = le_mem_ForceAlloc(ContextPoolRef); contextPtr->depth = depth; int item = 0; if (depth == 1) { item = i*(FAN_OUT+1)*(FAN_OUT+1); } if (depth == 2) { item = (j*(FAN_OUT+1)+(i+1))*(FAN_OUT+1); } else if (depth == 3) { item = (k*(FAN_OUT+1) + (j+1))*(FAN_OUT+1) + (i+1); } if (item >= FAN_OUT*(FAN_OUT+1)*(FAN_OUT+1)) { LE_TEST_FATAL("Result index %d outside test result array size %d!", item, FAN_OUT*(FAN_OUT+1)*(FAN_OUT+1)); } snprintf(childName, sizeof(childName), "%s-%d", threadName, i + 1); LE_TEST_INFO("Spawning thread '%s' (item %d).", childName, item); threadRef = le_thread_Create(childName, ThreadMainFunction, contextPtr); TestResults[item].createOk = !!threadRef; // Create a thread destructor that will release the Context object and the // Test Completion Object that we are going to pass to the child. le_thread_AddChildDestructor(threadRef, ThreadDestructor, contextPtr); LE_TEST_INFO("Thread '%s' destructor added.", childName); // Make every third leaf thread non-joinable and the rest joinable. // Non-leaves must be joinable to ensure join if (IsThreadJoinable(depth, i)) { le_thread_SetJoinable(threadRef); LE_TEST_INFO("Thread '%s' joinability set.", childName); } // Start the child thread. le_thread_Start(threadRef); LE_TEST_INFO("Thread '%s' started.", childName); // Remember the child's thread reference for later join attempt. children[i] = threadRef; } // Join with all the children. for (i = 0; i < FAN_OUT; i++) { void* threadReturnValue; int item = 0; if (depth == 1) { item = i*(FAN_OUT+1)*(FAN_OUT+1); } if (depth == 2) { item = (j*(FAN_OUT+1)+(i+1))*(FAN_OUT+1); } else if (depth == 3) { item = (k*(FAN_OUT+1)+(j+1))*(FAN_OUT+1) + (i+1); } if (item >= FAN_OUT*(FAN_OUT+1)*(FAN_OUT+1)) { LE_TEST_FATAL("Result index %d outside test result array size %d!", item, FAN_OUT*(FAN_OUT+1)*(FAN_OUT+1)); } snprintf(childName, sizeof(childName), "%s-%d", le_thread_GetMyName(), i + 1); if (IsThreadJoinable(depth, i)) { le_result_t result = le_thread_Join(children[i], &threadReturnValue); TestResults[item].joinOk = (result == LE_OK); if (result != LE_OK) { LE_TEST_INFO("Failed to join with thread '%s'.", childName); } else { LE_TEST_INFO("Successfully joined with thread '%s', which returned %p.", childName, threadReturnValue); TestResults[item].expectedJoin = (void*)depth; TestResults[item].actualJoin = threadReturnValue; } } else { // Do not try to join non-joinable threads. Result is undefined as thread // could have exited in the meantime and been recycled. TestResults[item].joinOk = false; } } }