2 * Copyright (C) 2008 Linus Torvalds
11 static void preload_index(struct index_state
*index
,
12 const struct pathspec
*pathspec
)
21 * Mostly randomly chosen maximum thread counts: we
22 * cap the parallelism to 20 threads, and we want
23 * to have at least 500 lstat's per thread for it to
24 * be worth starting a thread.
26 #define MAX_PARALLEL (20)
27 #define THREAD_COST (500)
31 struct index_state
*index
;
32 struct pathspec pathspec
;
36 static void *preload_thread(void *_data
)
39 struct thread_data
*p
= _data
;
40 struct index_state
*index
= p
->index
;
41 struct cache_entry
**cep
= index
->cache
+ p
->offset
;
42 struct cache_def cache
= CACHE_DEF_INIT
;
45 if (nr
+ p
->offset
> index
->cache_nr
)
46 nr
= index
->cache_nr
- p
->offset
;
49 struct cache_entry
*ce
= *cep
++;
54 if (S_ISGITLINK(ce
->ce_mode
))
58 if (ce_skip_worktree(ce
))
60 if (ce
->ce_flags
& CE_FSMONITOR_VALID
)
62 if (!ce_path_match(index
, ce
, &p
->pathspec
, NULL
))
64 if (threaded_has_symlink_leading_path(&cache
, ce
->name
, ce_namelen(ce
)))
66 if (lstat(ce
->name
, &st
))
68 if (ie_match_stat(index
, ce
, &st
, CE_MATCH_RACY_IS_DIRTY
|CE_MATCH_IGNORE_FSMONITOR
))
71 mark_fsmonitor_valid(ce
);
73 cache_def_clear(&cache
);
77 static void preload_index(struct index_state
*index
,
78 const struct pathspec
*pathspec
)
80 int threads
, i
, work
, offset
;
81 struct thread_data data
[MAX_PARALLEL
];
82 uint64_t start
= getnanotime();
84 if (!core_preload_index
)
87 threads
= index
->cache_nr
/ THREAD_COST
;
88 if ((index
->cache_nr
> 1) && (threads
< 2) && git_env_bool("GIT_FORCE_PRELOAD_TEST", 0))
92 if (threads
> MAX_PARALLEL
)
93 threads
= MAX_PARALLEL
;
95 work
= DIV_ROUND_UP(index
->cache_nr
, threads
);
96 memset(&data
, 0, sizeof(data
));
97 for (i
= 0; i
< threads
; i
++) {
98 struct thread_data
*p
= data
+i
;
101 copy_pathspec(&p
->pathspec
, pathspec
);
105 if (pthread_create(&p
->pthread
, NULL
, preload_thread
, p
))
106 die("unable to create threaded lstat");
108 for (i
= 0; i
< threads
; i
++) {
109 struct thread_data
*p
= data
+i
;
110 if (pthread_join(p
->pthread
, NULL
))
111 die("unable to join threaded lstat");
113 trace_performance_since(start
, "preload index");
117 int read_index_preload(struct index_state
*index
,
118 const struct pathspec
*pathspec
)
120 int retval
= read_index(index
);
122 preload_index(index
, pathspec
);