Browse code

fmap: antistress mutex only in linux, some cleanup

aCaB authored on 2009/10/10 22:39:31
Showing 1 changed files
... ...
@@ -24,9 +24,6 @@
24 24
 #include "clamav-config.h"
25 25
 #endif
26 26
 
27
-#define _XOPEN_SOURCE 500
28
-#define _BSD_SOURCE
29
-
30 27
 #include <sys/types.h>
31 28
 #include <sys/stat.h>
32 29
 #include <string.h>
... ...
@@ -37,8 +34,9 @@
37 37
 #endif
38 38
 #endif
39 39
 
40
+#ifdef C_LINUX
40 41
 #include <pthread.h>
41
-
42
+#endif
42 43
 
43 44
 #include "others.h"
44 45
 #include "cltypes.h"
... ...
@@ -59,9 +57,25 @@
59 59
 #define UNPAGE_THRSHLD_HI 8*1024*1024
60 60
 #define READAHEAD_PAGES 8
61 61
 
62
-/* DON'T ASK ME */
62
+#ifdef C_LINUX
63
+/*
64
+   WORKAROUND
65
+   Relieve some stress on mmap_sem.
66
+   When mmap_sem is heavily hammered, the scheduler
67
+   tends to fail to wake us up properly.
68
+*/
63 69
 pthread_mutex_t fmap_mutex = PTHREAD_MUTEX_INITIALIZER;
70
+#define fmap_lock pthread_mutex_lock(&fmap_mutex)
71
+#define fmap_unlock pthread_mutex_unlock(&fmap_mutex);
72
+#else
73
+#define fmap_lock
74
+#define fmap_unlock
75
+#endif
76
+
64 77
 
78
+/* pread proto here in order to avoid the use of XOPEN and BSD_SOURCE
79
+   which may in turn prevent some mmap constants to be defined */
80
+ssize_t pread(int fd, void *buf, size_t count, off_t offset);
65 81
 
66 82
 static unsigned int fmap_align_items(unsigned int sz, unsigned int al) {
67 83
     return sz / al + (sz % al != 0);
... ...
@@ -102,7 +116,7 @@ fmap_t *fmap(int fd, off_t offset, size_t len) {
102 102
     pages = fmap_align_items(len, pgsz);
103 103
     hdrsz = fmap_align_to(sizeof(fmap_t) + pages * sizeof(uint32_t), pgsz);
104 104
     mapsz = pages * pgsz + hdrsz;
105
-    pthread_mutex_lock(&fmap_mutex);
105
+    fmap_lock;
106 106
 #if HAVE_MMAP
107 107
     if ((m = (fmap_t *)mmap(NULL, mapsz, PROT_READ | PROT_WRITE, MAP_PRIVATE|/*FIXME: MAP_POPULATE is ~8% faster but more memory intensive */ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) {
108 108
 	m = NULL;
... ...
@@ -115,12 +129,12 @@ fmap_t *fmap(int fd, off_t offset, size_t len) {
115 115
 #endif
116 116
     if(!m) {
117 117
 	cli_warnmsg("fmap: map allocation failed\n");
118
-	pthread_mutex_unlock(&fmap_mutex);
118
+	fmap_unlock;
119 119
 	return NULL;
120 120
     }
121 121
     /* fault the header while we still have the lock - we DO context switch here a lot here :@ */
122 122
     memset(m->bitmap, 0, sizeof(uint32_t) * pages);
123
-    pthread_mutex_unlock(&fmap_mutex);
123
+    fmap_unlock;
124 124
     m->fd = fd;
125 125
     m->dumb = dumb;
126 126
     m->mtime = st.st_mtime;
... ...
@@ -177,10 +191,10 @@ static void fmap_aging(fmap_t *m) {
177 177
 		/* we mark the page as seen */
178 178
 		m->bitmap[freeme[i]] = FM_MASK_SEEN;
179 179
 		/* and we mmap the page over so the kernel knows there's nothing good in there */
180
-		pthread_mutex_lock(&fmap_mutex);
180
+		fmap_lock;
181 181
 		if(mmap(pptr, m->pgsz, PROT_READ | PROT_WRITE, MAP_FIXED|MAP_PRIVATE|ANONYMOUS_MAP, -1, 0) == MAP_FAILED)
182 182
 		    cli_warnmsg("fmap_aging: kernel hates you\n");
183
-		pthread_mutex_unlock(&fmap_mutex);
183
+		fmap_unlock;
184 184
 	    }
185 185
 	    m->paged -= avail;
186 186
 #ifdef FMAPDEBUG
... ...
@@ -198,13 +212,14 @@ static int fmap_readpage(fmap_t *m, unsigned int first_page, unsigned int count,
198 198
     uint32_t s;
199 199
     unsigned int i, page = first_page, force_read = 0;
200 200
 
201
-    pthread_mutex_lock(&fmap_mutex);
201
+    fmap_lock;
202 202
     for(i=0; i<count; i++) { /* prefault */
203 203
     	/* Not worth checking if the page is already paged, just ping each */
204 204
 	/* Also not worth reusing the loop below */
205
-    	volatile char faultme = ((char *)m)[(first_page+i) * m->pgsz + m->hdrsz];
205
+	volatile char faultme;
206
+	faultme = ((char *)m)[(first_page+i) * m->pgsz + m->hdrsz];
206 207
     }
207
-    pthread_mutex_unlock(&fmap_mutex);
208
+    fmap_unlock;
208 209
 #ifdef FMAPDEBUG
209 210
     m->page_needs += count;
210 211
     m->page_locks += lock_count;
... ...
@@ -301,13 +316,11 @@ static void *fmap_need(fmap_t *m, size_t at, size_t len, int lock) {
301 301
     unsigned int first_page, last_page, lock_count;
302 302
     char *ret;
303 303
 
304
-    if(!len) {
305
-//	cli_warnmsg("fmap: attempted void need\n");
304
+    if(!len)
306 305
 	return NULL;
307
-    }
308 306
 
309 307
     if(!CLI_ISCONTAINED(0, m->len, at, len)) {
310
-      //	cli_warnmsg("fmap: attempted oof need\n");
308
+	cli_warnmsg("fmap: attempted oof need\n");
311 309
 	return NULL;
312 310
     }
313 311
 
... ...
@@ -381,8 +394,6 @@ void fmap_unneed_off(fmap_t *m, size_t at, size_t len) {
381 381
 	return;
382 382
     }
383 383
 
384
-//    cli_errmsg("FMAPDBG: unneed_off map %p at %u len %u\n", m, at, len);
385
-
386 384
     first_page = fmap_which_page(m, at);
387 385
     last_page = fmap_which_page(m, at + len - 1);
388 386
 
... ...
@@ -392,7 +403,6 @@ void fmap_unneed_off(fmap_t *m, size_t at, size_t len) {
392 392
 }
393 393
 
394 394
 void fmap_unneed_ptr(fmap_t *m, void *ptr, size_t len) {
395
-//    cli_errmsg("FMAPDBG: unneed_ptr map %p at %p len %u\n", m, ptr, len);
396 395
     fmap_unneed_off(m, (char *)ptr - (char *)m - m->hdrsz, len);
397 396
 }
398 397
 
... ...
@@ -418,9 +428,9 @@ void funmap(fmap_t *m) {
418 418
 #if HAVE_MMAP
419 419
     if(!m->dumb) {
420 420
 	size_t len = m->pages * m->pgsz + m->hdrsz;
421
-	pthread_mutex_lock(&fmap_mutex);
421
+	fmap_lock;
422 422
 	munmap((void *)m, len);
423
-	pthread_mutex_unlock(&fmap_mutex);
423
+	fmap_unlock;
424 424
     } else
425 425
 #endif
426 426
 	free((void *)m);
... ...
@@ -434,7 +444,7 @@ void *fmap_need_offstr(fmap_t *m, size_t at, size_t len_hint) {
434 434
 	len_hint = m->len - at;
435 435
 
436 436
     if(!CLI_ISCONTAINED(0, m->len, at, len_hint)) {
437
-      //	cli_warnmsg("fmap: attempted oof need_str\n");
437
+	cli_warnmsg("fmap: attempted oof need_str\n");
438 438
 	return NULL;
439 439
     }
440 440
 
... ...
@@ -474,7 +484,7 @@ void *fmap_gets(fmap_t *m, char *dst, size_t *at, size_t max_len) {
474 474
     size_t len = MIN(max_len-1, m->len - *at), fullen = len;
475 475
 
476 476
     if(!len || !CLI_ISCONTAINED(0, m->len, *at, len)) {
477
-        //cli_warnmsg("fmap: attempted oof need_str\n");
477
+        cli_warnmsg("fmap: attempted oof need_str\n");
478 478
 	return NULL;
479 479
     }
480 480