//--------------------------------------------------------------------------------- // // Little Color Management System, multithread extensions // Copyright (c) 1998-2023 Marti Maria Saguer, all rights reserved // // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // //--------------------------------------------------------------------------------- #include "threaded_internal.h" // This is the threading support. Unfortunately, it has to be platform-dependent because // windows does not support pthreads. #ifdef CMS_IS_WINDOWS_ #define WIN32_LEAN_AND_MEAN 1 #include // To pass parameter to the thread typedef struct { _cmsTransform2Fn worker; _cmsWorkSlice* param; } thread_adaptor_param; // This is an adaptor to the native thread on windows static DWORD WINAPI thread_adaptor(LPVOID p) { thread_adaptor_param* ap = (thread_adaptor_param*)p; _cmsWorkSlice* s = ap->param; ap->worker(s->CMMcargo, s->InputBuffer, s->OutputBuffer, s->PixelsPerLine, s->LineCount, s->Stride); _cmsFree(0, p); return 0; } // This function creates a thread and executes it. The thread calls the worker function // with the given parameters. cmsHANDLE _cmsThrCreateWorker(cmsContext ContextID, _cmsTransform2Fn worker, _cmsWorkSlice* param) { DWORD ThreadID; thread_adaptor_param* p; HANDLE handle; p = (thread_adaptor_param*)_cmsMalloc(0, sizeof(thread_adaptor_param)); if (p == NULL) return NULL; p->worker = worker; p->param = param; handle = CreateThread(NULL, 0, thread_adaptor, (LPVOID) p, 0, &ThreadID); if (handle == NULL) { cmsSignalError(ContextID, cmsERROR_UNDEFINED, "Cannot create thread"); } return (cmsHANDLE)handle; } // Waits until given thread is ended void _cmsThrJoinWorker(cmsContext ContextID, cmsHANDLE hWorker) { if (WaitForSingleObject((HANDLE)hWorker, INFINITE) != WAIT_OBJECT_0) { cmsSignalError(ContextID, cmsERROR_UNDEFINED, "Cannot join thread"); } } // Returns the ideal number of threads the system can run cmsInt32Number _cmsThrIdealThreadCount(void) { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors; //Returns the number of processors in the system. } #else // Rest of the wide world #include #include // To pass parameter to the thread typedef struct { _cmsTransform2Fn worker; _cmsWorkSlice* param; } thread_adaptor_param; // This is the native thread on pthread static void* thread_adaptor(void* p) { thread_adaptor_param* ap = (thread_adaptor_param*)p; _cmsWorkSlice* s = ap->param; ap->worker(s->CMMcargo, s->InputBuffer, s->OutputBuffer, s->PixelsPerLine, s->LineCount, s->Stride); _cmsFree(0, p); return NULL; } // This function creates a thread and executes it. The thread calls the worker function // with the given parameters. cmsHANDLE _cmsThrCreateWorker(cmsContext ContextID, _cmsTransform2Fn worker, _cmsWorkSlice* param) { pthread_t threadId; thread_adaptor_param* p; p = (thread_adaptor_param*)_cmsMalloc(0, sizeof(thread_adaptor_param)); if (p == NULL) return NULL; p->worker = worker; p->param = param; int err = pthread_create(&threadId, NULL, thread_adaptor, p); if (err != 0) { cmsSignalError(ContextID, cmsERROR_UNDEFINED, "Cannot create thread [pthread error %d]", err); return NULL; } else return (cmsHANDLE) threadId; } // Waits until given thread is ended void _cmsThrJoinWorker(cmsContext ContextID, cmsHANDLE hWorker) { int err = pthread_join((pthread_t)hWorker, NULL); if (err != 0) { cmsSignalError(ContextID, cmsERROR_UNDEFINED, "Cannot join thread [pthread error %d]", err); } } cmsInt32Number _cmsThrIdealThreadCount(void) { long cores = sysconf(_SC_NPROCESSORS_ONLN); if (cores == -1L) return 1; else return (cmsInt32Number)cores; } #endif