mingw: add infrastructure for read-only file system level caches

Add a macro to mark code sections that only read from the file system,
along with a config option and documentation.

This facilitates implementation of relatively simple file system level
caches without the need to synchronize with the file system.

Enable read-only sections for 'git status' and preload_index.

Signed-off-by: Karsten Blees <blees@dcon.de>
This commit is contained in:
Karsten Blees
2013-09-08 14:23:27 +02:00
committed by Johannes Schindelin
parent 32d5356b2c
commit abb83bcc6a
6 changed files with 33 additions and 0 deletions

View File

@@ -670,6 +670,12 @@ relatively high IO latencies. When enabled, Git will do the
index comparison to the filesystem data in parallel, allowing index comparison to the filesystem data in parallel, allowing
overlapping IO's. Defaults to true. overlapping IO's. Defaults to true.
core.fscache::
Enable additional caching of file system data for some operations.
+
Git for Windows uses this to bulk-read and cache lstat data of entire
directories (instead of doing lstat file by file).
core.unsetenvvars:: core.unsetenvvars::
Windows-only: comma-separated list of environment variables' Windows-only: comma-separated list of environment variables'
names that need to be unset before spawning any other process. names that need to be unset before spawning any other process.

View File

@@ -1558,6 +1558,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
PATHSPEC_PREFER_FULL, PATHSPEC_PREFER_FULL,
prefix, argv); prefix, argv);
enable_fscache(1);
if (status_format != STATUS_FORMAT_PORCELAIN && if (status_format != STATUS_FORMAT_PORCELAIN &&
status_format != STATUS_FORMAT_PORCELAIN_V2) status_format != STATUS_FORMAT_PORCELAIN_V2)
progress_flag = REFRESH_PROGRESS; progress_flag = REFRESH_PROGRESS;

View File

@@ -244,6 +244,7 @@ enum hide_dotfiles_type {
static int core_restrict_inherited_handles = -1; static int core_restrict_inherited_handles = -1;
static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
static char *unset_environment_variables; static char *unset_environment_variables;
int core_fscache;
int mingw_core_config(const char *var, const char *value, int mingw_core_config(const char *var, const char *value,
const struct config_context *ctx, void *cb) const struct config_context *ctx, void *cb)
@@ -256,6 +257,11 @@ int mingw_core_config(const char *var, const char *value,
return 0; return 0;
} }
if (!strcmp(var, "core.fscache")) {
core_fscache = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "core.unsetenvvars")) { if (!strcmp(var, "core.unsetenvvars")) {
if (!value) if (!value)
return config_error_nonbool(var); return config_error_nonbool(var);

View File

@@ -11,6 +11,8 @@ typedef _sigset_t sigset_t;
#undef _POSIX_THREAD_SAFE_FUNCTIONS #undef _POSIX_THREAD_SAFE_FUNCTIONS
#endif #endif
extern int core_fscache;
struct config_context; struct config_context;
int mingw_core_config(const char *var, const char *value, int mingw_core_config(const char *var, const char *value,
const struct config_context *ctx, void *cb); const struct config_context *ctx, void *cb);

View File

@@ -1493,6 +1493,21 @@ static inline int is_missing_file_error(int errno_)
return (errno_ == ENOENT || errno_ == ENOTDIR); return (errno_ == ENOENT || errno_ == ENOTDIR);
} }
/*
* Enable/disable a read-only cache for file system data on platforms that
* support it.
*
* Implementing a live-cache is complicated and requires special platform
* support (inotify, ReadDirectoryChangesW...). enable_fscache shall be used
* to mark sections of git code that extensively read from the file system
* without modifying anything. Implementations can use this to cache e.g. stat
* data or even file content without the need to synchronize with the file
* system.
*/
#ifndef enable_fscache
#define enable_fscache(x) /* noop */
#endif
int cmd_main(int, const char **); int cmd_main(int, const char **);
/* /*

View File

@@ -132,6 +132,7 @@ void preload_index(struct index_state *index,
pthread_mutex_init(&pd.mutex, NULL); pthread_mutex_init(&pd.mutex, NULL);
} }
enable_fscache(1);
for (i = 0; i < threads; i++) { for (i = 0; i < threads; i++) {
struct thread_data *p = data+i; struct thread_data *p = data+i;
int err; int err;
@@ -167,6 +168,8 @@ void preload_index(struct index_state *index,
trace2_data_intmax("index", NULL, "preload/sum_lstat", t2_sum_lstat); trace2_data_intmax("index", NULL, "preload/sum_lstat", t2_sum_lstat);
trace2_region_leave("index", "preload", NULL); trace2_region_leave("index", "preload", NULL);
enable_fscache(0);
} }
int repo_read_index_preload(struct repository *repo, int repo_read_index_preload(struct repository *repo,