NTSTATUS LwRtlCreateThreadPool( PLW_THREAD_POOL* ppPool, PLW_THREAD_POOL_ATTRIBUTES pAttrs ) { NTSTATUS status = STATUS_SUCCESS; PLW_THREAD_POOL pPool = NULL; int i = 0; int numCpus = 0; status = LW_RTL_ALLOCATE_AUTO(&pPool); GOTO_ERROR_ON_STATUS(status); status = LwErrnoToNtStatus(pthread_mutex_init(&pPool->Lock, NULL)); GOTO_ERROR_ON_STATUS(status); status = LwErrnoToNtStatus(pthread_cond_init(&pPool->Event, NULL)); GOTO_ERROR_ON_STATUS(status); numCpus = LwRtlGetCpuCount(); if (GetDelegateAttr(pAttrs)) { status = AcquireDelegatePool(&pPool->pDelegate); GOTO_ERROR_ON_STATUS(status); } else { pPool->ulEventThreadCount = GetTaskThreadsAttr(pAttrs, numCpus); if (pPool->ulEventThreadCount) { status = LW_RTL_ALLOCATE_ARRAY_AUTO( &pPool->pEventThreads, pPool->ulEventThreadCount); GOTO_ERROR_ON_STATUS(status); for (i = 0; i < pPool->ulEventThreadCount; i++) { status = InitEventThread(pPool, pAttrs, &pPool->pEventThreads[i], i % numCpus); GOTO_ERROR_ON_STATUS(status); } } } status = InitWorkThreads(&pPool->WorkThreads, pAttrs, numCpus); GOTO_ERROR_ON_STATUS(status); *ppPool = pPool; cleanup: return status; error: LwRtlFreeThreadPool(&pPool); goto cleanup; }
NTSTATUS LwRtlCreateThreadPool( PLW_THREAD_POOL* ppPool, PLW_THREAD_POOL_ATTRIBUTES pAttrs ) { NTSTATUS status = STATUS_SUCCESS; PLW_THREAD_POOL pPool = NULL; int i = 0; int numCpus = 0; ULONG ulFdLimit = 0; #if defined(_SC_NPROCESSORS_ONLN) numCpus = sysconf(_SC_NPROCESSORS_ONLN); if (numCpus < 0) { numCpus = 1; } #else numCpus = 1; #endif GOTO_ERROR_ON_STATUS(status = LW_RTL_ALLOCATE_AUTO(&pPool)); GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus(pthread_mutex_init(&pPool->Lock, NULL))); GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus(pthread_cond_init(&pPool->Event, NULL))); if (GetDelegateAttr(pAttrs)) { status = AcquireDelegatePool(&pPool->pDelegate); GOTO_ERROR_ON_STATUS(status); } else { pPool->ulEventThreadCount = GetTaskThreadsAttr(pAttrs, numCpus); pPool->ulNextEventThread = 0; status = GetFdLimit(&ulFdLimit); GOTO_ERROR_ON_STATUS(status); /* * Each thread needs 2 fds for the notification pipe. * This check will limit us to 1/4 of the process fd limit. * This is particularly important on Solaris which has a very * low default limit of 256. */ if (pPool->ulEventThreadCount > ulFdLimit / 8) { pPool->ulEventThreadCount = ulFdLimit / 8; } if (pPool->ulEventThreadCount) { GOTO_ERROR_ON_STATUS(status = LW_RTL_ALLOCATE_ARRAY_AUTO( &pPool->pEventThreads, pPool->ulEventThreadCount)); for (i = 0; i < pPool->ulEventThreadCount; i++) { GOTO_ERROR_ON_STATUS(status = SelectThreadInit(pAttrs, &pPool->pEventThreads[i])); } } } status = InitWorkThreads(&pPool->WorkThreads, pAttrs, numCpus); GOTO_ERROR_ON_STATUS(status); *ppPool = pPool; error: return status; }