summaryrefslogtreecommitdiff
path: root/packfile.c
diff options
context:
space:
mode:
authorJonathan Tan <jonathantanmy@google.com>2017-08-18 15:20:20 -0700
committerJunio C Hamano <gitster@pobox.com>2017-08-23 15:12:06 -0700
commitf0e17e86e1b1030b2719f3d6e9d4124c9b5bc480 (patch)
tree8bbe6ceefe3fa6bdd8f5325925cb6319deeca1e5 /packfile.c
parent0317f45576a0b48c90c4b023fa572a000633946c (diff)
downloadgit-f0e17e86e1b1030b2719f3d6e9d4124c9b5bc480.tar.gz
pack: move release_pack_memory()
The function unuse_one_window() needs to be temporarily made global. Its scope will be restored to static in a subsequent commit. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'packfile.c')
-rw-r--r--packfile.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/packfile.c b/packfile.c
index 6edc432288..8daa74ad11 100644
--- a/packfile.c
+++ b/packfile.c
@@ -208,3 +208,52 @@ struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
return p;
}
+
+static void scan_windows(struct packed_git *p,
+ struct packed_git **lru_p,
+ struct pack_window **lru_w,
+ struct pack_window **lru_l)
+{
+ struct pack_window *w, *w_l;
+
+ for (w_l = NULL, w = p->windows; w; w = w->next) {
+ if (!w->inuse_cnt) {
+ if (!*lru_w || w->last_used < (*lru_w)->last_used) {
+ *lru_p = p;
+ *lru_w = w;
+ *lru_l = w_l;
+ }
+ }
+ w_l = w;
+ }
+}
+
+int unuse_one_window(struct packed_git *current)
+{
+ struct packed_git *p, *lru_p = NULL;
+ struct pack_window *lru_w = NULL, *lru_l = NULL;
+
+ if (current)
+ scan_windows(current, &lru_p, &lru_w, &lru_l);
+ for (p = packed_git; p; p = p->next)
+ scan_windows(p, &lru_p, &lru_w, &lru_l);
+ if (lru_p) {
+ munmap(lru_w->base, lru_w->len);
+ pack_mapped -= lru_w->len;
+ if (lru_l)
+ lru_l->next = lru_w->next;
+ else
+ lru_p->windows = lru_w->next;
+ free(lru_w);
+ pack_open_windows--;
+ return 1;
+ }
+ return 0;
+}
+
+void release_pack_memory(size_t need)
+{
+ size_t cur = pack_mapped;
+ while (need >= (cur - pack_mapped) && unuse_one_window(NULL))
+ ; /* nothing */
+}