提交 8e6280fc 编写于 作者: A Alexander Alekhin

ocl: binary program cache

上级 f8ad2893
......@@ -261,6 +261,8 @@ public:
void setUseSVM(bool enabled);
struct Impl;
inline Impl* getImpl() const { return (Impl*)p; }
//protected:
Impl* p;
};
......
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_UTILS_FILESYSTEM_HPP
#define OPENCV_UTILS_FILESYSTEM_HPP
namespace cv { namespace utils { namespace fs {
CV_EXPORTS bool exists(const cv::String& path);
CV_EXPORTS bool isDirectory(const cv::String& path);
CV_EXPORTS cv::String getcwd();
CV_EXPORTS bool createDirectory(const cv::String& path);
CV_EXPORTS bool createDirectories(const cv::String& path);
#ifdef __OPENCV_BUILD
// TODO
//CV_EXPORTS cv::String getTempDirectory();
/**
* @brief Returns directory to store OpenCV cache files
* Create sub-directory in common OpenCV cache directory if it doesn't exist.
* @param sub_directory_name name of sub-directory. NULL or "" value asks to return root cache directory.
* @param configuration_name optional name of configuration parameter name which overrides default behavior.
* @return Path to cache directory. Returns empty string if cache directories support is not available. Returns "disabled" if cache disabled by user.
*/
CV_EXPORTS cv::String getCacheDirectory(const char* sub_directory_name, const char* configuration_name = NULL);
#endif
}}} // namespace
#endif // OPENCV_UTILS_FILESYSTEM_HPP
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_UTILS_FILESYSTEM_PRIVATE_HPP
#define OPENCV_UTILS_FILESYSTEM_PRIVATE_HPP
// TODO Move to CMake?
#ifndef OPENCV_HAVE_FILESYSTEM_SUPPORT
# if defined(__EMSCRIPTEN__) || defined(__native_client__)
/* no support */
# elif defined __ANDROID__ || defined __linux__ || defined _WIN32 || \
defined __FreeBSD__ || defined __bsdi__
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1
# elif defined(__APPLE__)
# include <TargetConditionals.h>
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (!defined(TARGET_OS_OSX) && !TARGET_OS_IPHONE)
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX only
# endif
# else
/* unknown */
# endif
# ifndef OPENCV_HAVE_FILESYSTEM_SUPPORT
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 0
# endif
#endif
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
namespace cv { namespace utils { namespace fs {
/**
* File-based lock object.
*
* Provides interprocess synchronization mechanism.
* Platform dependent.
*
* Supports multiple readers / single writer access pattern (RW / readers–writer / shared-exclusive lock).
*
* File must exist.
* File can't be re-used (for example, I/O operations via std::fstream is not safe)
*/
class CV_EXPORTS FileLock {
public:
explicit FileLock(const char* fname);
~FileLock();
void lock(); //< acquire exclusive (writer) lock
void unlock(); //< release exclusive (writer) lock
void lock_shared(); //< acquire sharable (reader) lock
void unlock_shared(); //< release sharable (reader) lock
struct Impl;
protected:
Impl* pImpl;
private:
FileLock(const FileLock&); // disabled
FileLock& operator=(const FileLock&); // disabled
};
}}} // namespace
#endif
#endif // OPENCV_UTILS_FILESYSTEM_PRIVATE_HPP
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_UTILS_LOCK_HPP
#define OPENCV_UTILS_LOCK_HPP
namespace cv { namespace utils {
/** @brief A simple scoped lock (RAII-style locking for exclusive/write access).
*
* Emulate std::lock_guard (C++11), partially std::unique_lock (C++11),
*/
template <class _Mutex>
class lock_guard {
public:
typedef _Mutex Mutex;
explicit inline lock_guard(Mutex &m) : mutex_(&m) { mutex_->lock(); }
inline ~lock_guard() { if (mutex_) mutex_->unlock(); }
inline void release()
{
CV_DbgAssert(mutex_);
mutex_->unlock();
mutex_ = NULL;
}
private:
Mutex* mutex_;
private:
lock_guard(const lock_guard&); // disabled
lock_guard& operator=(const lock_guard&); // disabled
};
/** @brief A shared scoped lock (RAII-style locking for shared/reader access).
*
* Emulate boost::shared_lock_guard, subset of std::shared_lock (C++14),
*/
template <class _Mutex>
class shared_lock_guard {
public:
typedef _Mutex Mutex;
explicit inline shared_lock_guard(Mutex &m) : mutex_(&m) { mutex_->lock_shared(); }
inline ~shared_lock_guard() { if (mutex_) mutex_->unlock_shared(); }
inline void release()
{
CV_DbgAssert(mutex_);
mutex_->unlock_shared();
mutex_ = NULL;
}
protected:
Mutex* mutex_;
private:
shared_lock_guard(const shared_lock_guard&); // disabled
shared_lock_guard& operator=(const shared_lock_guard&); // disabled
};
/** @brief An optional simple scoped lock (RAII-style locking for exclusive/write access).
*
* Doesn't lock if mutex pointer is NULL.
*
* @sa lock_guard
*/
template <class _Mutex>
class optional_lock_guard {
public:
typedef _Mutex Mutex;
explicit inline optional_lock_guard(Mutex* m) : mutex_(m) { if (mutex_) mutex_->lock(); }
inline ~optional_lock_guard() { if (mutex_) mutex_->unlock(); }
private:
Mutex* mutex_;
private:
optional_lock_guard(const optional_lock_guard&); // disabled
optional_lock_guard& operator=(const optional_lock_guard&); // disabled
};
/** @brief An optional shared scoped lock (RAII-style locking for shared/reader access).
*
* Doesn't lock if mutex pointer is NULL.
*
* @sa shared_lock_guard
*/
template <class _Mutex>
class optional_shared_lock_guard {
public:
typedef _Mutex Mutex;
explicit inline optional_shared_lock_guard(Mutex* m) : mutex_(m) { if (mutex_) mutex_->lock_shared(); }
inline ~optional_shared_lock_guard() { if (mutex_) mutex_->unlock_shared(); }
protected:
Mutex* mutex_;
private:
optional_shared_lock_guard(const optional_shared_lock_guard&); // disabled
optional_shared_lock_guard& operator=(const optional_shared_lock_guard&); // disabled
};
}} // namespace
#endif // OPENCV_UTILS_LOCK_HPP
......@@ -42,6 +42,8 @@
#include "precomp.hpp"
#include "opencv2/core/utils/filesystem.hpp"
#if defined _WIN32 || defined WINCE
# include <windows.h>
const char dir_separators[] = "/\\";
......@@ -169,6 +171,12 @@ static bool isDir(const cv::String& path, DIR* dir)
#endif
}
bool cv::utils::fs::isDirectory(const cv::String& path)
{
CV_INSTRUMENT_REGION()
return isDir(path, NULL);
}
static bool wildcmp(const char *string, const char *wild)
{
// Based on wildcmp written by Jack Handy - <A href="mailto:jakkhandy@hotmail.com">jakkhandy@hotmail.com</A>
......
此差异已折叠。
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "precomp.hpp"
#include <opencv2/core/utils/configuration.private.hpp>
#include <opencv2/core/utils/logger.hpp>
#include "opencv2/core/utils/filesystem.private.hpp"
#include "opencv2/core/utils/filesystem.hpp"
//#define DEBUG_FS_UTILS
#ifdef DEBUG_FS_UTILS
#include <iostream>
#define DBG(...) __VA_ARGS__
#else
#define DBG(...)
#endif
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <direct.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#elif defined __linux__ || defined __APPLE__
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#endif
namespace cv { namespace utils { namespace fs {
static inline
bool isPathSeparator(char c)
{
return c == '/' || c == '\\';
}
bool exists(const cv::String& path)
{
CV_INSTRUMENT_REGION()
#if defined _WIN32 || defined WINCE
BOOL status = TRUE;
{
WIN32_FILE_ATTRIBUTE_DATA all_attrs;
#ifdef WINRT
wchar_t wpath[MAX_PATH];
size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH);
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
status = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &all_attrs);
#else
status = ::GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &all_attrs);
#endif
}
return !!status;
#else
struct stat stat_buf;
return (0 == stat(path.c_str(), &stat_buf));
#endif
}
cv::String getcwd()
{
CV_INSTRUMENT_REGION()
cv::AutoBuffer<char, 4096> buf;
#if defined WIN32 || defined _WIN32 || defined WINCE
#ifdef WINRT
return cv::String();
#else
DWORD sz = GetCurrentDirectoryA(0, NULL);
buf.allocate((size_t)sz);
sz = GetCurrentDirectoryA((DWORD)buf.size(), (char*)buf);
return cv::String((char*)buf, (size_t)sz);
#endif
#elif defined __linux__ || defined __APPLE__
for(;;)
{
char* p = ::getcwd((char*)buf, buf.size());
if (p == NULL)
{
if (errno == ERANGE)
{
buf.allocate(buf.size() * 2);
continue;
}
return cv::String();
}
break;
}
return cv::String((char*)buf, (size_t)strlen((char*)buf));
#else
return cv::String();
#endif
}
bool createDirectory(const cv::String& path)
{
CV_INSTRUMENT_REGION()
#if defined WIN32 || defined _WIN32 || defined WINCE
#ifdef WINRT
wchar_t wpath[MAX_PATH];
size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH);
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
int result = CreateDirectoryA(wpath, NULL) ? 0 : -1;
#else
int result = _mkdir(path.c_str());
#endif
#elif defined __linux__ || defined __APPLE__
int result = mkdir(path.c_str(), 0777);
#else
int result = -1;
#endif
if (result == -1)
{
return isDirectory(path);
}
return true;
}
bool createDirectories(const cv::String& path_)
{
cv::String path = path_;
for (;;)
{
char last_char = path.empty() ? 0 : path[path.length() - 1];
if (last_char == '/' || last_char == '\\')
{
path = path.substr(0, path.length() - 1);
continue;
}
break;
}
if (path.empty() || path == "./" || path == ".\\" || path == ".")
return true;
if (isDirectory(path))
return true;
size_t pos = path.rfind('/');
if (pos == cv::String::npos)
pos = path.rfind('\\');
if (pos != cv::String::npos)
{
cv::String parent_directory = path.substr(0, pos);
if (!parent_directory.empty())
{
if (!createDirectories(parent_directory))
return false;
}
}
return createDirectory(path);
}
#ifdef _WIN32
struct FileLock::Impl
{
Impl(const char* fname)
{
// http://support.microsoft.com/kb/316609
int numRetries = 5;
do
{
handle = ::CreateFileA(fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == handle)
{
if (ERROR_SHARING_VIOLATION == GetLastError())
{
numRetries--;
Sleep(250);
continue;
}
else
{
CV_ErrorNoReturn_(Error::StsAssert, ("Can't open lock file: %s", fname));
}
}
break;
} while (numRetries > 0);
}
~Impl()
{
if (INVALID_HANDLE_VALUE != handle)
{
::CloseHandle(handle);
}
}
bool lock()
{
OVERLAPPED overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
return !!::LockFileEx(handle, LOCKFILE_EXCLUSIVE_LOCK, 0, MAXDWORD, MAXDWORD, &overlapped);
}
bool unlock()
{
OVERLAPPED overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
return !!::UnlockFileEx(handle, 0, MAXDWORD, MAXDWORD, &overlapped);
}
bool lock_shared()
{
OVERLAPPED overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
return !!::LockFileEx(handle, 0, 0, MAXDWORD, MAXDWORD, &overlapped);
}
bool unlock_shared()
{
return unlock();
}
HANDLE handle;
private:
Impl(const Impl&); // disabled
Impl& operator=(const Impl&); // disabled
};
#elif defined __linux__ || defined __APPLE__
struct FileLock::Impl
{
Impl(const char* fname)
{
handle = ::open(fname, O_RDWR);
CV_Assert(handle != -1);
}
~Impl()
{
if (handle >= 0)
::close(handle);
}
bool lock()
{
struct ::flock l;
std::memset(&l, 0, sizeof(l));
l.l_type = F_WRLCK;
l.l_whence = SEEK_SET;
l.l_start = 0;
l.l_len = 0;
DBG(std::cout << "Lock..." << std::endl);
bool res = -1 != ::fcntl(handle, F_SETLKW, &l);
return res;
}
bool unlock()
{
struct ::flock l;
std::memset(&l, 0, sizeof(l));
l.l_type = F_UNLCK;
l.l_whence = SEEK_SET;
l.l_start = 0;
l.l_len = 0;
DBG(std::cout << "Unlock..." << std::endl);
bool res = -1 != ::fcntl(handle, F_SETLK, &l);
return res;
}
bool lock_shared()
{
struct ::flock l;
std::memset(&l, 0, sizeof(l));
l.l_type = F_RDLCK;
l.l_whence = SEEK_SET;
l.l_start = 0;
l.l_len = 0;
DBG(std::cout << "Lock read..." << std::endl);
bool res = -1 != ::fcntl(handle, F_SETLKW, &l);
return res;
}
bool unlock_shared()
{
return unlock();
}
int handle;
private:
Impl(const Impl&); // disabled
Impl& operator=(const Impl&); // disabled
};
#endif
FileLock::FileLock(const char* fname)
: pImpl(new Impl(fname))
{
// nothing
}
FileLock::~FileLock()
{
delete pImpl;
pImpl = NULL;
}
void FileLock::lock() { CV_Assert(pImpl->lock()); }
void FileLock::unlock() { CV_Assert(pImpl->unlock()); }
void FileLock::lock_shared() { CV_Assert(pImpl->lock_shared()); }
void FileLock::unlock_shared() { CV_Assert(pImpl->unlock_shared()); }
cv::String getCacheDirectory(const char* sub_directory_name, const char* configuration_name)
{
String cache_path;
if (configuration_name)
{
cache_path = utils::getConfigurationParameterString(configuration_name, "");
}
if (cache_path.empty())
{
cv::String default_cache_path;
#ifdef _WIN32
char tmp_path_buf[MAX_PATH+1] = {0};
DWORD res = GetTempPath(MAX_PATH, tmp_path_buf);
if (res > 0 && res <= MAX_PATH)
{
default_cache_path = tmp_path_buf;
}
#elif defined __ANDROID__
// no defaults
#elif defined __APPLE__
const char* tmpdir_env = getenv("TMPDIR");
if (tmpdir_env && utils::fs::isDirectory(tmpdir_env))
{
default_cache_path = tmpdir_env;
}
else
{
default_cache_path = "/tmp/";
CV_LOG_WARNING(NULL, "Using world accessible cache directory. This may be not secure: " << default_cache_path);
}
#elif defined __linux__
// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
if (default_cache_path.empty())
{
const char* xdg_cache_env = getenv("XDG_CACHE_HOME");
if (xdg_cache_env && xdg_cache_env[0] && utils::fs::isDirectory(xdg_cache_env))
{
default_cache_path = xdg_cache_env;
}
}
if (default_cache_path.empty())
{
const char* home_env = getenv("HOME");
if (home_env && home_env[0] && utils::fs::isDirectory(home_env))
{
cv::String home_path = home_env;
cv::String home_cache_path = home_path + "/.cache/";
if (utils::fs::isDirectory(home_cache_path))
{
default_cache_path = home_cache_path;
}
}
}
if (default_cache_path.empty())
{
const char* temp_path = "/var/tmp/";
if (utils::fs::isDirectory(temp_path))
{
default_cache_path = temp_path;
CV_LOG_WARNING(NULL, "Using world accessible cache directory. This may be not secure: " << default_cache_path);
}
}
if (default_cache_path.empty())
{
default_cache_path = "/tmp/";
CV_LOG_WARNING(NULL, "Using world accessible cache directory. This may be not secure: " << default_cache_path);
}
#else
// no defaults
#endif
CV_LOG_VERBOSE(NULL, 0, "default_cache_path = " << default_cache_path);
if (!default_cache_path.empty())
{
if (utils::fs::isDirectory(default_cache_path))
{
default_cache_path += "/opencv/" CV_VERSION "/";
if (sub_directory_name && sub_directory_name[0] != '\0')
default_cache_path += cv::String(sub_directory_name) + "/";
if (!utils::fs::createDirectories(default_cache_path))
{
CV_LOG_DEBUG(NULL, "Can't create OpenCV cache sub-directory: " << default_cache_path);
}
else
{
cache_path = default_cache_path;
}
}
else
{
CV_LOG_INFO(NULL, "Can't find default cache directory (does it exist?): " << default_cache_path);
}
}
else
{
CV_LOG_DEBUG(NULL, "OpenCV has no support to discover default cache directory on the current platform");
}
}
else
{
if (cache_path == "disabled")
return cache_path;
if (!isDirectory(cache_path))
{
CV_LOG_WARNING(NULL, "Specified non-existed directory, creating OpenCV sub-directory for caching purposes: " << cache_path);
if (!createDirectories(cache_path))
{
CV_LOG_ERROR(NULL, "Can't create OpenCV cache sub-directory: " << cache_path);
cache_path.clear();
}
}
}
CV_Assert(cache_path.empty() || utils::fs::isDirectory(cache_path));
if (!cache_path.empty())
{
if (!isPathSeparator(cache_path[cache_path.size() - 1]))
{
cache_path += '/';
}
}
return cache_path;
}
}}} // namespace
#endif // OPENCV_HAVE_FILESYSTEM_SUPPORT
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册