xref: /dflybsd-src/sbin/hammer/cache.c (revision 78418745092c20e1fe6c2c579522c105d19211f1)
161aeeb33SMatthew Dillon /*
261aeeb33SMatthew Dillon  * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
361aeeb33SMatthew Dillon  *
461aeeb33SMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
561aeeb33SMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
661aeeb33SMatthew Dillon  *
761aeeb33SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
861aeeb33SMatthew Dillon  * modification, are permitted provided that the following conditions
961aeeb33SMatthew Dillon  * are met:
1061aeeb33SMatthew Dillon  *
1161aeeb33SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
1261aeeb33SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
1361aeeb33SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
1461aeeb33SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
1561aeeb33SMatthew Dillon  *    the documentation and/or other materials provided with the
1661aeeb33SMatthew Dillon  *    distribution.
1761aeeb33SMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
1861aeeb33SMatthew Dillon  *    contributors may be used to endorse or promote products derived
1961aeeb33SMatthew Dillon  *    from this software without specific, prior written permission.
2061aeeb33SMatthew Dillon  *
2161aeeb33SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2261aeeb33SMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2361aeeb33SMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2461aeeb33SMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
2561aeeb33SMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2661aeeb33SMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
2761aeeb33SMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2861aeeb33SMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2961aeeb33SMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3061aeeb33SMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3161aeeb33SMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3261aeeb33SMatthew Dillon  * SUCH DAMAGE.
3361aeeb33SMatthew Dillon  *
34ac76a28dSMatthew Dillon  * $DragonFly: src/sbin/hammer/cache.c,v 1.5 2008/05/16 18:39:03 dillon Exp $
3561aeeb33SMatthew Dillon  */
3661aeeb33SMatthew Dillon 
3761aeeb33SMatthew Dillon #include "hammer_util.h"
3861aeeb33SMatthew Dillon 
3961aeeb33SMatthew Dillon static int CacheUse;
4062997e7bSTomohiro Kusumi static int CacheMax = HAMMER_BUFSIZE * 1024;
4161aeeb33SMatthew Dillon static TAILQ_HEAD(, cache_info) CacheList = TAILQ_HEAD_INITIALIZER(CacheList);
4261aeeb33SMatthew Dillon 
4325ee129eSTomohiro Kusumi int
hammer_parse_cache_size(const char * arg)4425ee129eSTomohiro Kusumi hammer_parse_cache_size(const char *arg)
4525ee129eSTomohiro Kusumi {
4625ee129eSTomohiro Kusumi 	char *ptr;
4725ee129eSTomohiro Kusumi 	int size = strtol(arg, &ptr, 0);
4825ee129eSTomohiro Kusumi 
4925ee129eSTomohiro Kusumi 	switch(*ptr) {
5025ee129eSTomohiro Kusumi 	case 'm':
5125ee129eSTomohiro Kusumi 	case 'M':
5225ee129eSTomohiro Kusumi 		size *= 1024;
5325ee129eSTomohiro Kusumi 		/* fall through */
5425ee129eSTomohiro Kusumi 	case 'k':
5525ee129eSTomohiro Kusumi 	case 'K':
5625ee129eSTomohiro Kusumi 		size *= 1024;
5725ee129eSTomohiro Kusumi 		++ptr;
5825ee129eSTomohiro Kusumi 		break;
5925ee129eSTomohiro Kusumi 	case '\0':
6025ee129eSTomohiro Kusumi 	case ':':
6125ee129eSTomohiro Kusumi 		/* bytes if no suffix */
6225ee129eSTomohiro Kusumi 		break;
6325ee129eSTomohiro Kusumi 	default:
6425ee129eSTomohiro Kusumi 		return(-1);
6525ee129eSTomohiro Kusumi 	}
6625ee129eSTomohiro Kusumi 
6725ee129eSTomohiro Kusumi 	if (*ptr == ':') {
6825ee129eSTomohiro Kusumi 		UseReadAhead = strtol(ptr + 1, NULL, 0);
6925ee129eSTomohiro Kusumi 		UseReadBehind = -UseReadAhead;
7025ee129eSTomohiro Kusumi 	}
7125ee129eSTomohiro Kusumi 	if (size < 1024 * 1024)
7225ee129eSTomohiro Kusumi 		size = 1024 * 1024;
7325ee129eSTomohiro Kusumi 	if (UseReadAhead < 0)
7425ee129eSTomohiro Kusumi 		return(-1);
7525ee129eSTomohiro Kusumi 	if (UseReadAhead * HAMMER_BUFSIZE / size / 16) {
7625ee129eSTomohiro Kusumi 		UseReadAhead = size / 16 / HAMMER_BUFSIZE;
7725ee129eSTomohiro Kusumi 		UseReadBehind = -UseReadAhead;
7825ee129eSTomohiro Kusumi 	}
7925ee129eSTomohiro Kusumi 
806c7ae023STomohiro Kusumi 	CacheMax = size;
816c7ae023STomohiro Kusumi 	return(0);
820faa08a1SMatthew Dillon }
830faa08a1SMatthew Dillon 
840faa08a1SMatthew Dillon void
hammer_cache_add(cache_info_t cache)85*78418745STomohiro Kusumi hammer_cache_add(cache_info_t cache)
8661aeeb33SMatthew Dillon {
87b46b99bfSMatthew Dillon 	TAILQ_INSERT_HEAD(&CacheList, cache, entry);
8861aeeb33SMatthew Dillon 	CacheUse += HAMMER_BUFSIZE;
8961aeeb33SMatthew Dillon }
9061aeeb33SMatthew Dillon 
9161aeeb33SMatthew Dillon void
hammer_cache_del(cache_info_t cache)92*78418745STomohiro Kusumi hammer_cache_del(cache_info_t cache)
9361aeeb33SMatthew Dillon {
9461aeeb33SMatthew Dillon 	TAILQ_REMOVE(&CacheList, cache, entry);
9561aeeb33SMatthew Dillon 	CacheUse -= HAMMER_BUFSIZE;
9661aeeb33SMatthew Dillon }
9761aeeb33SMatthew Dillon 
9861aeeb33SMatthew Dillon void
hammer_cache_used(cache_info_t cache)99*78418745STomohiro Kusumi hammer_cache_used(cache_info_t cache)
100b46b99bfSMatthew Dillon {
101b46b99bfSMatthew Dillon 	TAILQ_REMOVE(&CacheList, cache, entry);
102b46b99bfSMatthew Dillon 	TAILQ_INSERT_TAIL(&CacheList, cache, entry);
103b46b99bfSMatthew Dillon }
104b46b99bfSMatthew Dillon 
105b46b99bfSMatthew Dillon void
hammer_cache_flush(void)10661aeeb33SMatthew Dillon hammer_cache_flush(void)
10761aeeb33SMatthew Dillon {
108*78418745STomohiro Kusumi 	cache_info_t cache;
109*78418745STomohiro Kusumi 	cache_info_t first = NULL;
110a7bdb8f3SMatthew Dillon 	int count = 0;
11161aeeb33SMatthew Dillon 
112f254e677STomohiro Kusumi 	if (CacheUse >= CacheMax) {
11361aeeb33SMatthew Dillon 		while ((cache = TAILQ_FIRST(&CacheList)) != NULL) {
114281de955STomohiro Kusumi 			if (cache == first)
115281de955STomohiro Kusumi 				break; /* seen this ref'd before */
116281de955STomohiro Kusumi 
11761aeeb33SMatthew Dillon 			if (cache->refs) {
118281de955STomohiro Kusumi 				if (first == NULL)
119281de955STomohiro Kusumi 					first = cache;
1201d05d4e0STomohiro Kusumi 				hammer_cache_used(cache);
121281de955STomohiro Kusumi 				count++;
12261aeeb33SMatthew Dillon 				continue;
12361aeeb33SMatthew Dillon 			}
124e827d884STomohiro Kusumi 			if (count >= (CacheUse / HAMMER_BUFSIZE)) {
12562997e7bSTomohiro Kusumi 				CacheMax += HAMMER_BUFSIZE * 512;
126281de955STomohiro Kusumi 				count = 0;
127a7bdb8f3SMatthew Dillon 			}
128281de955STomohiro Kusumi 
12961aeeb33SMatthew Dillon 			cache->refs = 1;
13061aeeb33SMatthew Dillon 			cache->delete = 1;
131c17fa600STomohiro Kusumi 			rel_buffer((buffer_info_t)cache);
13261aeeb33SMatthew Dillon 
133281de955STomohiro Kusumi 			if (CacheUse < CacheMax / 2)
134a7bdb8f3SMatthew Dillon 				break;
13561aeeb33SMatthew Dillon 		}
13661aeeb33SMatthew Dillon 	}
137f254e677STomohiro Kusumi }
13861aeeb33SMatthew Dillon 
139