Path: blob/master/Utilities/cmzstd/lib/common/threading.c
5012 views
/**1* Copyright (c) 2016 Tino Reichardt2* All rights reserved.3*4* You can contact the author at:5* - zstdmt source repository: https://github.com/mcmilk/zstdmt6*7* This source code is licensed under both the BSD-style license (found in the8* LICENSE file in the root directory of this source tree) and the GPLv2 (found9* in the COPYING file in the root directory of this source tree).10* You may select, at your option, one of the above-listed licenses.11*/1213/**14* This file will hold wrapper for systems, which do not support pthreads15*/1617#include "threading.h"1819/* create fake symbol to avoid empty translation unit warning */20int g_ZSTD_threading_useless_symbol;2122#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)2324/**25* Windows minimalist Pthread Wrapper26*/272829/* === Dependencies === */30#include <process.h>31#include <errno.h>323334/* === Implementation === */3536typedef struct {37void* (*start_routine)(void*);38void* arg;39int initialized;40ZSTD_pthread_cond_t initialized_cond;41ZSTD_pthread_mutex_t initialized_mutex;42} ZSTD_thread_params_t;4344static unsigned __stdcall worker(void *arg)45{46void* (*start_routine)(void*);47void* thread_arg;4849/* Initialized thread_arg and start_routine and signal main thread that we don't need it50* to wait any longer.51*/52{53ZSTD_thread_params_t* thread_param = (ZSTD_thread_params_t*)arg;54thread_arg = thread_param->arg;55start_routine = thread_param->start_routine;5657/* Signal main thread that we are running and do not depend on its memory anymore */58ZSTD_pthread_mutex_lock(&thread_param->initialized_mutex);59thread_param->initialized = 1;60ZSTD_pthread_cond_signal(&thread_param->initialized_cond);61ZSTD_pthread_mutex_unlock(&thread_param->initialized_mutex);62}6364start_routine(thread_arg);6566return 0;67}6869int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,70void* (*start_routine) (void*), void* arg)71{72ZSTD_thread_params_t thread_param;73(void)unused;7475if (thread==NULL) return -1;76*thread = NULL;7778thread_param.start_routine = start_routine;79thread_param.arg = arg;80thread_param.initialized = 0;8182/* Setup thread initialization synchronization */83if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) {84/* Should never happen on Windows */85return -1;86}87if(ZSTD_pthread_mutex_init(&thread_param.initialized_mutex, NULL)) {88/* Should never happen on Windows */89ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);90return -1;91}9293/* Spawn thread */94*thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL);95if (*thread==NULL) {96ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);97ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);98return errno;99}100101/* Wait for thread to be initialized */102ZSTD_pthread_mutex_lock(&thread_param.initialized_mutex);103while(!thread_param.initialized) {104ZSTD_pthread_cond_wait(&thread_param.initialized_cond, &thread_param.initialized_mutex);105}106ZSTD_pthread_mutex_unlock(&thread_param.initialized_mutex);107ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);108ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);109110return 0;111}112113int ZSTD_pthread_join(ZSTD_pthread_t thread)114{115DWORD result;116117if (!thread) return 0;118119result = WaitForSingleObject(thread, INFINITE);120CloseHandle(thread);121122switch (result) {123case WAIT_OBJECT_0:124return 0;125case WAIT_ABANDONED:126return EINVAL;127default:128return GetLastError();129}130}131132#endif /* ZSTD_MULTITHREAD */133134#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)135136#define ZSTD_DEPS_NEED_MALLOC137#include "zstd_deps.h"138139int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)140{141assert(mutex != NULL);142*mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));143if (!*mutex)144return 1;145return pthread_mutex_init(*mutex, attr);146}147148int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)149{150assert(mutex != NULL);151if (!*mutex)152return 0;153{154int const ret = pthread_mutex_destroy(*mutex);155ZSTD_free(*mutex);156return ret;157}158}159160int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)161{162assert(cond != NULL);163*cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));164if (!*cond)165return 1;166return pthread_cond_init(*cond, attr);167}168169int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)170{171assert(cond != NULL);172if (!*cond)173return 0;174{175int const ret = pthread_cond_destroy(*cond);176ZSTD_free(*cond);177return ret;178}179}180181#endif182183184