Commit a15c550db8b0552902e58c9bf2194005fb7fb0e9

Vicent Marti 2011-11-16T14:09:44

threads: Fix the shared global state with TLS See `global.c` for a description of what we're doing. When libgit2 is built with GIT_THREADS support, the threading system must be explicitly initialized with `git_threads_init()`.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
diff --git a/include/git2.h b/include/git2.h
index ad92809..14c090e 100644
--- a/include/git2.h
+++ b/include/git2.h
@@ -11,6 +11,7 @@
 #include "git2/version.h"
 
 #include "git2/common.h"
+#include "git2/threads.h"
 #include "git2/errors.h"
 #include "git2/zlib.h"
 
diff --git a/include/git2/common.h b/include/git2/common.h
index ef279ea..eee918a 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -7,7 +7,6 @@
 #ifndef INCLUDE_git_common_h__
 #define INCLUDE_git_common_h__
 
-#include "thread-utils.h"
 #include <time.h>
 #include <stdlib.h>
 
@@ -38,18 +37,6 @@
 # define GIT_EXTERN(type) extern type
 #endif
 
-/** Declare a public TLS symbol exported for application use. */
-#if __GNUC__ >= 4
-# define GIT_EXTERN_TLS(type) extern \
-					__attribute__((visibility("default"))) \
-					GIT_TLS \
-					type
-#elif defined(_MSC_VER)
-# define GIT_EXTERN_TLS(type) __declspec(dllexport) GIT_TLS type
-#else
-# define GIT_EXTERN_TLS(type) extern GIT_TLS type
-#endif
-
 /** Declare a function as always inlined. */
 #if defined(_MSC_VER)
 # define GIT_INLINE(type) static __inline type
diff --git a/include/git2/thread-utils.h b/include/git2/thread-utils.h
deleted file mode 100644
index 81c62d1..0000000
--- a/include/git2/thread-utils.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2009-2011 the libgit2 contributors
- *
- * This file is part of libgit2, distributed under the GNU GPL v2 with
- * a Linking Exception. For full terms see the included COPYING file.
- */
-#ifndef INCLUDE_git_thread_utils_h__
-#define INCLUDE_git_thread_utils_h__
-
-/*
- * How TLS works is compiler+platform dependant
- * Sources: http://en.wikipedia.org/wiki/Thread-Specific_Storage
- *			http://predef.sourceforge.net/precomp.html
- */
-
-#ifdef GIT_THREADS
-#	define GIT_HAS_TLS 1
-
-/* No TLS in Cygwin */
-#	if defined(__CHECKER__) || defined(__CYGWIN__)
-#		undef GIT_HAS_TLS
-#		define GIT_TLS
-
-/* No TLS in Mach binaries for Mac OS X */
-#	elif defined(__APPLE__) && defined(__MACH__)
-#		undef GIT_TLS
-#		define GIT_TLS
-
-/* Normal TLS for GCC */
-#	elif defined(__GNUC__) || \
-		defined(__SUNPRO_C) || \
-		defined(__SUNPRO_CC) || \
-		defined(__xlc__) || \
-		defined(__xlC__)
-#		define GIT_TLS __thread
-
-/* ICC may run on Windows or Linux */
-#	elif defined(__INTEL_COMPILER)
-#		if defined(_WIN32) || defined(_WIN32_CE)
-#		define GIT_TLS __declspec(thread)
-#		else
-#		define GIT_TLS __thread
-#		endif
-
-/* Declspec for MSVC in Win32 */
-#	elif defined(_WIN32) || \
-		defined(_WIN32_CE) || \
-		defined(__BORLANDC__)
-#		define GIT_TLS __declspec(thread)
-
-/* Other platform; no TLS */
-#	else
-#		undef GIT_HAS_TLS
-#		define GIT_TLS /* nothing: tls vars are thread-global */
-#	endif
-#else /* Disable TLS if libgit2 is not threadsafe */
-#	define GIT_TLS
-#endif /* GIT_THREADS */
-
-#endif /* INCLUDE_git_thread_utils_h__ */
diff --git a/include/git2/threads.h b/include/git2/threads.h
new file mode 100644
index 0000000..85472a4
--- /dev/null
+++ b/include/git2/threads.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009-2011 the libgit2 contributors
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_threads_h__
+#define INCLUDE_git_threads_h__
+
+#include "common.h"
+
+/**
+ * @file git2/threads.h
+ * @brief Library level thread functions
+ * @defgroup git_thread Threading functions
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Init the threading system.
+ *
+ * If libgit2 has been built with GIT_THREADS
+ * on, this function must be called once before
+ * any other library functions.
+ *
+ * If libgit2 has been built without GIT_THREADS
+ * support, this function is a no-op.
+ */
+GIT_EXTERN(void) git_threads_init(void);
+
+/**
+ * Shutdown the threading system.
+ *
+ * If libgit2 has been built with GIT_THREADS
+ * on, this function must be called before shutting
+ * down the library.
+ *
+ * If libgit2 has been built without GIT_THREADS
+ * support, this function is a no-op.
+ */
+GIT_EXTERN(void) git_threads_shutdown(void);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/src/common.h b/src/common.h
index f7a41d4..727a08e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -8,7 +8,6 @@
 #define INCLUDE_common_h__
 
 #include "git2/common.h"
-#include "git2/thread-utils.h"
 #include "cc-compat.h"
 
 #include <assert.h>
diff --git a/src/errors.c b/src/errors.c
index 18afff3..81770e7 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -5,13 +5,9 @@
  * a Linking Exception. For full terms see the included COPYING file.
  */
 #include "common.h"
-#include "git2/thread-utils.h" /* for GIT_TLS */
-#include "thread-utils.h" /* for GIT_TLS */
-
+#include "global.h"
 #include <stdarg.h>
 
-static GIT_TLS char g_last_error[1024];
-
 static struct {
 	int num;
 	const char *str;
@@ -59,19 +55,26 @@ const char *git_strerror(int num)
 	return "Unknown error";
 }
 
+#define ERROR_MAX_LEN 1024
+
 void git___rethrow(const char *msg, ...)
 {
-	char new_error[1024];
+	char new_error[ERROR_MAX_LEN];
+	char *last_error;
 	char *old_error = NULL;
 
 	va_list va;
 
+	last_error = GIT_GLOBAL->error.last;
+
 	va_start(va, msg);
-	vsnprintf(new_error, sizeof(new_error), msg, va);
+	vsnprintf(new_error, ERROR_MAX_LEN, msg, va);
 	va_end(va);
 
-	old_error = git__strdup(g_last_error);
-	snprintf(g_last_error, sizeof(g_last_error), "%s \n	- %s", new_error, old_error);
+	old_error = git__strdup(last_error);
+
+	snprintf(last_error, ERROR_MAX_LEN, "%s \n	- %s", new_error, old_error);
+
 	git__free(old_error);
 }
 
@@ -80,19 +83,22 @@ void git___throw(const char *msg, ...)
 	va_list va;
 
 	va_start(va, msg);
-	vsnprintf(g_last_error, sizeof(g_last_error), msg, va);
+	vsnprintf(GIT_GLOBAL->error.last, ERROR_MAX_LEN, msg, va);
 	va_end(va);
 }
 
 const char *git_lasterror(void)
 {
-	if (!g_last_error[0])
+	char *last_error = GIT_GLOBAL->error.last;
+
+	if (!last_error[0])
 		return NULL;
 
-	return g_last_error;
+	return last_error;
 }
 
 void git_clearerror(void)
 {
-	g_last_error[0] = '\0';
+	char *last_error = GIT_GLOBAL->error.last;
+	last_error[0] = '\0';
 }
diff --git a/src/global.c b/src/global.c
new file mode 100644
index 0000000..8ef286e
--- /dev/null
+++ b/src/global.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2009-2011 the libgit2 contributors
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "global.h"
+#include "git2/threads.h" 
+#include "thread-utils.h"
+
+/**
+ * Handle the global state with TLS
+ *
+ * If libgit2 is built with GIT_THREADS enabled,
+ * the `git_threads_init()` function must be called
+ * before calling any other function of the library.
+ *
+ * This function allocates a TLS index (using pthreads
+ * or the native Win32 API) to store the global state
+ * on a per-thread basis.
+ *
+ * Any internal method that requires global state will
+ * then call `git__global_state()` which returns a pointer
+ * to the global state structure; this pointer is lazily
+ * allocated on each thread.
+ *
+ * Before shutting down the library, the
+ * `git_threads_shutdown` method must be called to free
+ * the previously reserved TLS index.
+ *
+ * If libgit2 is built without threading support, the
+ * `git__global_statestate()` call returns a pointer to a single,
+ * statically allocated global state. The `git_thread_`
+ * functions are not available in that case.
+ */
+
+#if defined(GIT_THREADS) && defined(GIT_WIN32)
+
+static DWORD _tls_index;
+static int _tls_init = 0;
+
+void git_threads_init(void)
+{
+	if (_tls_init)
+		return;
+
+	_tls_index = TlsAlloc();
+	_tls_init = 1;
+}
+
+void git_threads_shutdown(void)
+{
+	TlsFree(_tls_index);
+	_tls_init = 0;
+}
+
+git_global_st *git__global_state(void)
+{
+	void *ptr;
+
+	if ((ptr = TlsGetValue(_tls_index)) != NULL)
+		return ptr;
+
+	ptr = malloc(sizeof(git_global_st));
+	if (!ptr)
+		return NULL;
+
+	memset(ptr, 0x0, sizeof(git_global_st));
+	TlsSetValue(_tls_index, ptr);
+	return ptr;
+}
+
+#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
+
+static pthread_key_t _tls_key;
+static int _tls_init = 0;
+
+static void cb__free_status(void *st)
+{
+	free(st);
+}
+
+void git_threads_init(void)
+{
+	if (_tls_init)
+		return;
+
+	pthread_key_create(&_tls_key, &cb__free_status);
+	_tls_init = 1;
+}
+
+void git_threads_shutdown(void)
+{
+	pthread_key_delete(_tls_key);
+	_tls_init = 0;
+}
+
+git_global_st *git__global_state(void)
+{
+	void *ptr;
+
+	if ((ptr = pthread_getspecific(_tls_key)) != NULL)
+		return ptr;
+
+	ptr = malloc(sizeof(git_global_st));
+	if (!ptr)
+		return NULL;
+
+	memset(ptr, 0x0, sizeof(git_global_st));
+	pthread_setspecific(_tls_key, ptr);
+	return ptr;
+}
+
+#else
+
+static git_global_st __state;
+
+void git_threads_init(void)
+{
+	/* noop */ 
+}
+
+void git_threads_shutdown(void)
+{
+	/* noop */
+}
+
+git_global_st *git__global_state(void)
+{
+	return &__state;
+}
+
+#endif /* GIT_THREADS */
diff --git a/src/global.h b/src/global.h
new file mode 100644
index 0000000..641f47c
--- /dev/null
+++ b/src/global.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009-2011 the libgit2 contributors
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_global_h__
+#define INCLUDE_global_h__
+
+#include "mwindow.h"
+
+typedef struct {
+	struct {
+		char last[1024];
+	} error;
+
+	git_mwindow_ctl mem_ctl;
+} git_global_st;
+
+git_global_st *git__global_state(void);
+
+#define GIT_GLOBAL (git__global_state())
+
+#endif
diff --git a/src/mwindow.c b/src/mwindow.c
index 126268f..8dc4573 100644
--- a/src/mwindow.c
+++ b/src/mwindow.c
@@ -10,6 +10,7 @@
 #include "vector.h"
 #include "fileops.h"
 #include "map.h"
+#include "global.h"
 
 #define DEFAULT_WINDOW_SIZE \
 	(sizeof(void*) >= 8 \
@@ -20,21 +21,15 @@
 	((1024 * 1024) * (sizeof(void*) >= 8 ? 8192ULL : 256UL))
 
 /*
- * We need this because each process is only allowed a specific amount
- * of memory. Making it writable should generate one instance per
- * process, but we still need to set a couple of variables.
+ * These are the global options for mmmap limits.
+ * TODO: allow the user to change these
  */
-
-static git_mwindow_ctl ctl = {
-	0,
-	0,
+static struct {
+	size_t window_size;
+	size_t mapped_limit;
+} _mw_options = {
 	DEFAULT_WINDOW_SIZE,
 	DEFAULT_MAPPED_LIMIT,
-	0,
-	0,
-	0,
-	0,
-	{0, 0, 0, 0, 0}
 };
 
 /*
@@ -43,28 +38,29 @@ static git_mwindow_ctl ctl = {
  */
 void git_mwindow_free_all(git_mwindow_file *mwf)
 {
+	git_mwindow_ctl *ctl = &GIT_GLOBAL->mem_ctl;
 	unsigned int i;
 	/*
 	 * Remove these windows from the global list
 	 */
-	for (i = 0; i < ctl.windowfiles.length; ++i){
-		if (git_vector_get(&ctl.windowfiles, i) == mwf) {
-			git_vector_remove(&ctl.windowfiles, i);
+	for (i = 0; i < ctl->windowfiles.length; ++i){
+		if (git_vector_get(&ctl->windowfiles, i) == mwf) {
+			git_vector_remove(&ctl->windowfiles, i);
 			break;
 		}
 	}
 
-	if (ctl.windowfiles.length == 0) {
-		git_vector_free(&ctl.windowfiles);
-		ctl.windowfiles.contents = NULL;
+	if (ctl->windowfiles.length == 0) {
+		git_vector_free(&ctl->windowfiles);
+		ctl->windowfiles.contents = NULL;
 	}
 
 	while (mwf->windows) {
 		git_mwindow *w = mwf->windows;
 		assert(w->inuse_cnt == 0);
 
-		ctl.mapped -= w->window_map.len;
-		ctl.open_windows--;
+		ctl->mapped -= w->window_map.len;
+		ctl->open_windows--;
 
 		git_futils_mmap_free(&w->window_map);
 
@@ -115,6 +111,7 @@ void git_mwindow_scan_lru(
  */
 static int git_mwindow_close_lru(git_mwindow_file *mwf)
 {
+	git_mwindow_ctl *ctl = &GIT_GLOBAL->mem_ctl;
 	unsigned int i;
 	git_mwindow *lru_w = NULL, *lru_l = NULL, **list = &mwf->windows;
 
@@ -122,16 +119,16 @@ static int git_mwindow_close_lru(git_mwindow_file *mwf)
 	if(mwf->windows)
 		git_mwindow_scan_lru(mwf, &lru_w, &lru_l);
 
-	for (i = 0; i < ctl.windowfiles.length; ++i) {
+	for (i = 0; i < ctl->windowfiles.length; ++i) {
 		git_mwindow *last = lru_w;
-		git_mwindow_file *cur = git_vector_get(&ctl.windowfiles, i);
+		git_mwindow_file *cur = git_vector_get(&ctl->windowfiles, i);
 		git_mwindow_scan_lru(cur, &lru_w, &lru_l);
 		if (lru_w != last)
 			list = &cur->windows;
 	}
 
 	if (lru_w) {
-		ctl.mapped -= lru_w->window_map.len;
+		ctl->mapped -= lru_w->window_map.len;
 		git_futils_mmap_free(&lru_w->window_map);
 
 		if (lru_l)
@@ -140,7 +137,7 @@ static int git_mwindow_close_lru(git_mwindow_file *mwf)
 			*list = lru_w->next;
 
 		git__free(lru_w);
-		ctl.open_windows--;
+		ctl->open_windows--;
 
 		return GIT_SUCCESS;
 	}
@@ -148,9 +145,14 @@ static int git_mwindow_close_lru(git_mwindow_file *mwf)
 	return git__throw(GIT_ERROR, "Failed to close memory window. Couln't find LRU");
 }
 
-static git_mwindow *new_window(git_mwindow_file *mwf, git_file fd, git_off_t size, git_off_t offset)
+static git_mwindow *new_window(
+	git_mwindow_file *mwf,
+	git_file fd,
+	git_off_t size,
+	git_off_t offset)
 {
-	size_t walign = ctl.window_size / 2;
+	git_mwindow_ctl *ctl = &GIT_GLOBAL->mem_ctl;
+	size_t walign = _mw_options.window_size / 2;
 	git_off_t len;
 	git_mwindow *w;
 
@@ -162,16 +164,16 @@ static git_mwindow *new_window(git_mwindow_file *mwf, git_file fd, git_off_t siz
 	w->offset = (offset / walign) * walign;
 
 	len = size - w->offset;
-	if (len > (git_off_t)ctl.window_size)
-		len = (git_off_t)ctl.window_size;
+	if (len > (git_off_t)_mw_options.window_size)
+		len = (git_off_t)_mw_options.window_size;
 
-	ctl.mapped += (size_t)len;
+	ctl->mapped += (size_t)len;
 
-	while(ctl.mapped_limit < ctl.mapped &&
-			git_mwindow_close_lru(mwf) == GIT_SUCCESS) {}
+	while (_mw_options.mapped_limit < ctl->mapped &&
+			git_mwindow_close_lru(mwf) == GIT_SUCCESS) /* nop */;
 
 	/*
-	 * We treat ctl.mapped_limit as a soft limit. If we can't find a
+	 * We treat _mw_options.mapped_limit as a soft limit. If we can't find a
 	 * window to close and are above the limit, we still mmap the new
 	 * window.
 	 */
@@ -179,14 +181,14 @@ static git_mwindow *new_window(git_mwindow_file *mwf, git_file fd, git_off_t siz
 	if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < GIT_SUCCESS)
 		goto cleanup;
 
-	ctl.mmap_calls++;
-	ctl.open_windows++;
+	ctl->mmap_calls++;
+	ctl->open_windows++;
 
-	if (ctl.mapped > ctl.peak_mapped)
-		ctl.peak_mapped = ctl.mapped;
+	if (ctl->mapped > ctl->peak_mapped)
+		ctl->peak_mapped = ctl->mapped;
 
-	if (ctl.open_windows > ctl.peak_open_windows)
-		ctl.peak_open_windows = ctl.open_windows;
+	if (ctl->open_windows > ctl->peak_open_windows)
+		ctl->peak_open_windows = ctl->open_windows;
 
 	return w;
 
@@ -199,9 +201,14 @@ cleanup:
  * Open a new window, closing the least recenty used until we have
  * enough space. Don't forget to add it to your list
  */
-unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor,
-								git_off_t offset, int extra, unsigned int *left)
+unsigned char *git_mwindow_open(
+	git_mwindow_file *mwf,
+	git_mwindow **cursor,
+	git_off_t offset,
+	int extra,
+	unsigned int *left)
 {
+	git_mwindow_ctl *ctl = &GIT_GLOBAL->mem_ctl;
 	git_mwindow *w = *cursor;
 
 	if (!w || !git_mwindow_contains(w, offset + extra)) {
@@ -229,7 +236,7 @@ unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor,
 
 	/* If we changed w, store it in the cursor */
 	if (w != *cursor) {
-		w->last_used = ctl.used_ctr++;
+		w->last_used = ctl->used_ctr++;
 		w->inuse_cnt++;
 		*cursor = w;
 	}
@@ -245,13 +252,14 @@ unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor,
 
 int git_mwindow_file_register(git_mwindow_file *mwf)
 {
+	git_mwindow_ctl *ctl = &GIT_GLOBAL->mem_ctl;
 	int error;
 
-	if (ctl.windowfiles.length == 0 &&
-		(error = git_vector_init(&ctl.windowfiles, 8, NULL)) < GIT_SUCCESS)
+	if (ctl->windowfiles.length == 0 &&
+		(error = git_vector_init(&ctl->windowfiles, 8, NULL)) < GIT_SUCCESS)
 		return error;
 
-	return git_vector_insert(&ctl.windowfiles, mwf);
+	return git_vector_insert(&ctl->windowfiles, mwf);
 }
 
 void git_mwindow_close(git_mwindow **window)
diff --git a/src/mwindow.h b/src/mwindow.h
index ec75f90..11c3aa8 100644
--- a/src/mwindow.h
+++ b/src/mwindow.h
@@ -10,7 +10,6 @@
 
 #include "map.h"
 #include "vector.h"
-#include "fileops.h"
 
 typedef struct git_mwindow {
 	struct git_mwindow *next;
@@ -29,8 +28,6 @@ typedef struct git_mwindow_file {
 typedef struct git_mwindow_ctl {
 	size_t mapped;
 	unsigned int open_windows;
-	size_t window_size; /* needs default value */
-	size_t mapped_limit; /* needs default value */
 	unsigned int mmap_calls;
 	unsigned int peak_open_windows;
 	size_t peak_mapped;
diff --git a/src/pack.c b/src/pack.c
index 429bb5e..ae954b9 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -5,11 +5,13 @@
  * a Linking Exception. For full terms see the included COPYING file.
  */
 
-#include "mwindow.h"
+#include "common.h"
 #include "odb.h"
 #include "pack.h"
 #include "delta-apply.h"
 #include "sha1_lookup.h"
+#include "mwindow.h"
+#include "fileops.h"
 
 #include "git2/oid.h"
 #include "git2/zlib.h"
diff --git a/src/thread-utils.h b/src/thread-utils.h
index 3361ed8..c555479 100644
--- a/src/thread-utils.h
+++ b/src/thread-utils.h
@@ -7,7 +7,7 @@
 #ifndef INCLUDE_thread_utils_h__
 #define INCLUDE_thread_utils_h__
 
-
+#include "common.h"
 
 /* Common operations even if threading has been disabled */
 typedef struct {