1 | /*- |
---|
2 | * See the file LICENSE for redistribution information. |
---|
3 | * |
---|
4 | * Copyright (c) 1996-2002 |
---|
5 | * Sleepycat Software. All rights reserved. |
---|
6 | */ |
---|
7 | #include "db_config.h" |
---|
8 | |
---|
9 | #ifndef lint |
---|
10 | static const char revid[] = "$Id: mp_method.c,v 1.1.1.1 2004-12-17 17:27:13 ghudson Exp $"; |
---|
11 | #endif /* not lint */ |
---|
12 | |
---|
13 | #ifndef NO_SYSTEM_INCLUDES |
---|
14 | #include <sys/types.h> |
---|
15 | |
---|
16 | #ifdef HAVE_RPC |
---|
17 | #include <rpc/rpc.h> |
---|
18 | #endif |
---|
19 | #endif |
---|
20 | |
---|
21 | #include "db_int.h" |
---|
22 | #include "dbinc/db_shash.h" |
---|
23 | #include "dbinc/mp.h" |
---|
24 | |
---|
25 | #ifdef HAVE_RPC |
---|
26 | #include "dbinc_auto/db_server.h" |
---|
27 | #include "dbinc_auto/rpc_client_ext.h" |
---|
28 | #endif |
---|
29 | |
---|
30 | static int __memp_set_cachesize __P((DB_ENV *, u_int32_t, u_int32_t, int)); |
---|
31 | static int __memp_set_mp_mmapsize __P((DB_ENV *, size_t)); |
---|
32 | |
---|
33 | /* |
---|
34 | * __memp_dbenv_create -- |
---|
35 | * Mpool specific creation of the DB_ENV structure. |
---|
36 | * |
---|
37 | * PUBLIC: void __memp_dbenv_create __P((DB_ENV *)); |
---|
38 | */ |
---|
39 | void |
---|
40 | __memp_dbenv_create(dbenv) |
---|
41 | DB_ENV *dbenv; |
---|
42 | { |
---|
43 | /* |
---|
44 | * !!! |
---|
45 | * Our caller has not yet had the opportunity to reset the panic |
---|
46 | * state or turn off mutex locking, and so we can neither check |
---|
47 | * the panic state or acquire a mutex in the DB_ENV create path. |
---|
48 | * |
---|
49 | * We default to 32 8K pages. We don't default to a flat 256K, because |
---|
50 | * some systems require significantly more memory to hold 32 pages than |
---|
51 | * others. For example, HP-UX with POSIX pthreads needs 88 bytes for |
---|
52 | * a POSIX pthread mutex and almost 200 bytes per buffer header, while |
---|
53 | * Solaris needs 24 and 52 bytes for the same structures. The minimum |
---|
54 | * number of hash buckets is 37. These contain a mutex also. |
---|
55 | */ |
---|
56 | dbenv->mp_bytes = |
---|
57 | 32 * ((8 * 1024) + sizeof(BH)) + 37 * sizeof(DB_MPOOL_HASH); |
---|
58 | dbenv->mp_ncache = 1; |
---|
59 | |
---|
60 | #ifdef HAVE_RPC |
---|
61 | if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) { |
---|
62 | dbenv->set_cachesize = __dbcl_env_cachesize; |
---|
63 | dbenv->set_mp_mmapsize = __dbcl_set_mp_mmapsize; |
---|
64 | dbenv->memp_dump_region = NULL; |
---|
65 | dbenv->memp_fcreate = __dbcl_memp_fcreate; |
---|
66 | dbenv->memp_nameop = NULL; |
---|
67 | dbenv->memp_register = __dbcl_memp_register; |
---|
68 | dbenv->memp_stat = __dbcl_memp_stat; |
---|
69 | dbenv->memp_sync = __dbcl_memp_sync; |
---|
70 | dbenv->memp_trickle = __dbcl_memp_trickle; |
---|
71 | } else |
---|
72 | #endif |
---|
73 | { |
---|
74 | dbenv->set_cachesize = __memp_set_cachesize; |
---|
75 | dbenv->set_mp_mmapsize = __memp_set_mp_mmapsize; |
---|
76 | dbenv->memp_dump_region = __memp_dump_region; |
---|
77 | dbenv->memp_fcreate = __memp_fcreate; |
---|
78 | dbenv->memp_nameop = __memp_nameop; |
---|
79 | dbenv->memp_register = __memp_register; |
---|
80 | dbenv->memp_stat = __memp_stat; |
---|
81 | dbenv->memp_sync = __memp_sync; |
---|
82 | dbenv->memp_trickle = __memp_trickle; |
---|
83 | } |
---|
84 | } |
---|
85 | |
---|
86 | /* |
---|
87 | * __memp_set_cachesize -- |
---|
88 | * Initialize the cache size. |
---|
89 | */ |
---|
90 | static int |
---|
91 | __memp_set_cachesize(dbenv, gbytes, bytes, ncache) |
---|
92 | DB_ENV *dbenv; |
---|
93 | u_int32_t gbytes, bytes; |
---|
94 | int ncache; |
---|
95 | { |
---|
96 | ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_cachesize"); |
---|
97 | |
---|
98 | /* Normalize the values. */ |
---|
99 | if (ncache == 0) |
---|
100 | ncache = 1; |
---|
101 | |
---|
102 | /* |
---|
103 | * You can only store 4GB-1 in an unsigned 32-bit value, so correct for |
---|
104 | * applications that specify 4GB cache sizes -- we know what they meant. |
---|
105 | */ |
---|
106 | if (gbytes / ncache == 4 && bytes == 0) { |
---|
107 | --gbytes; |
---|
108 | bytes = GIGABYTE - 1; |
---|
109 | } else { |
---|
110 | gbytes += bytes / GIGABYTE; |
---|
111 | bytes %= GIGABYTE; |
---|
112 | } |
---|
113 | |
---|
114 | /* Avoid too-large cache sizes, they result in a region size of zero. */ |
---|
115 | if (gbytes / ncache > 4 || (gbytes / ncache == 4 && bytes != 0)) { |
---|
116 | __db_err(dbenv, "individual cache size too large"); |
---|
117 | return (EINVAL); |
---|
118 | } |
---|
119 | |
---|
120 | /* |
---|
121 | * If the application requested less than 500Mb, increase the cachesize |
---|
122 | * by 25% and factor in the size of the hash buckets to account for our |
---|
123 | * overhead. (I'm guessing caches over 500Mb are specifically sized, |
---|
124 | * that is, it's a large server and the application actually knows how |
---|
125 | * much memory is available. We only document the 25% overhead number, |
---|
126 | * not the hash buckets, but I don't see a reason to confuse the issue, |
---|
127 | * it shouldn't matter to an application.) |
---|
128 | * |
---|
129 | * There is a minimum cache size, regardless. |
---|
130 | */ |
---|
131 | if (gbytes == 0) { |
---|
132 | if (bytes < 500 * MEGABYTE) |
---|
133 | bytes += (bytes / 4) + 37 * sizeof(DB_MPOOL_HASH); |
---|
134 | if (bytes / ncache < DB_CACHESIZE_MIN) |
---|
135 | bytes = ncache * DB_CACHESIZE_MIN; |
---|
136 | } |
---|
137 | |
---|
138 | dbenv->mp_gbytes = gbytes; |
---|
139 | dbenv->mp_bytes = bytes; |
---|
140 | dbenv->mp_ncache = ncache; |
---|
141 | |
---|
142 | return (0); |
---|
143 | } |
---|
144 | |
---|
145 | /* |
---|
146 | * __memp_set_mp_mmapsize -- |
---|
147 | * Set the maximum mapped file size. |
---|
148 | */ |
---|
149 | static int |
---|
150 | __memp_set_mp_mmapsize(dbenv, mp_mmapsize ) |
---|
151 | DB_ENV *dbenv; |
---|
152 | size_t mp_mmapsize; |
---|
153 | { |
---|
154 | dbenv->mp_mmapsize = mp_mmapsize; |
---|
155 | return (0); |
---|
156 | } |
---|