diff --git a/dist/api_flags b/dist/api_flags index 43bc20b45..d2c8bbfb7 100644 --- a/dist/api_flags +++ b/dist/api_flags @@ -213,7 +213,7 @@ DbEnv.set_flags DB_DIRECT_DB # Don't buffer databases in the OS DB_DSYNC_DB # Set O_DSYNC on the databases DB_HOTBACKUP_IN_PROGRESS # Inhibit bulk loading optimization - DB_MPOOL_AIO # Use asynchronous buffer-pool writeback + DB_MPOOL_AIO __PIN=0x00100000 # Use asynchronous buffer-pool writeback DB_MULTIVERSION # Multiversion concurrency control DB_NOLOCKING # Set locking/mutex behavior DB_NOMMAP # Don't mmap the underlying file @@ -276,7 +276,7 @@ DbEnv.txn_begin DB_TXN_FAMILY # Cursors and child txns are # independent but lock-compatible DB_TXN_SNAPSHOT # Snapshot isolation - DB_TXN_SNAPSHOT_SAFE # Serializable snapshot isolation (SSI) + DB_TXN_SNAPSHOT_SAFE __PIN=0x00000800 # Serializable snapshot isolation (SSI) DB_TXN_SYNC # Always sync log on commit DB_TXN_WAIT # Always wait for locks in this txn DB_TXN_WRITE_NOSYNC # Write the log but don't sync diff --git a/dist/api_flags.c b/dist/api_flags.c index eb20da023..6faa1a002 100644 --- a/dist/api_flags.c +++ b/dist/api_flags.c @@ -27,13 +27,14 @@ typedef struct { API **api, **api_end; u_int value; /* Bit value */ + int pinned; /* Value was pinned via __PIN= */ } FLAG; FLAG **flag_list, **flag_end; int verbose; char *progname; -int add_entry(char *, char *); +int add_entry(char *, char *, u_int); void define_print(char *, u_int); void dump_api(void); void dump_flags(void); @@ -129,16 +130,43 @@ parse() * with leading whitespace is a flag name. */ if (isspace(buf[0])) { - if ((p = strtok(buf, " \t")) == NULL || *p == '#') + char *flag, *extra; + u_int pin; + + if ((flag = strtok(buf, " \t")) == NULL || *flag == '#') continue; /* A flag without an API makes no sense. */ if (api == NULL) goto format; + /* + * An optional "__PIN=" token after a flag name + * forces that flag to a fixed bit and reserves the bit + * from the API's greedy allocation. This lets new + * flags take high, unused bits without renumbering the + * existing public flag values (preserving the ABI of + * the generated constants). + */ + pin = 0; + if ((extra = strtok(NULL, " \t")) != NULL && + *extra != '#') { + if (strncmp(extra, + "__PIN=", sizeof("__PIN=") - 1) != 0) + goto format; + pin = (u_int)strtoul( + extra + sizeof("__PIN=") - 1, NULL, 0); + if (pin == 0) + goto format; + if ((extra = strtok(NULL, " \t")) != NULL && + *extra != '#') + goto format; + } + /* Enter the pair into the array. */ - if (add_entry(api, p)) + if (add_entry(api, flag, pin)) return (1); + continue; } else { if ((p = strtok(buf, " \t")) == NULL) continue; @@ -158,7 +186,7 @@ format: fprintf(stderr, "%s: format error: line %d\n", progname, lc); } int -add_entry(char *api_name, char *flag_name) +add_entry(char *api_name, char *flag_name, u_int pin) { FLAG **fpp, *fp; API **app, *ap, **p; @@ -225,6 +253,12 @@ add_entry(char *api_name, char *flag_name) fp = *fpp; ++fp->api_cnt; + /* Record an explicit pinned bit value, if given. */ + if (pin != 0) { + fp->value = pin; + fp->pinned = 1; + } + /* Check to see if this API is already listed for this flag. */ for (p = fp->api; p != NULL && *p != NULL && p < fp->api_end; ++p) if (strcmp(api_name, (*p)->name) == 0) { @@ -313,12 +347,34 @@ generate_flags() qsort(flag_list, (u_int)(flag_end - flag_list), sizeof(FLAG *), flag_cmp_api_cnt); + /* + * Reserve every pinned flag's fixed bit in each API that uses it, + * before the greedy pass, so the greedy allocator never hands that + * bit to another flag. Pinned flags keep their explicit value and + * are skipped below. + */ + for (fpp = flag_list; *fpp != NULL; ++fpp) { + if (!(*fpp)->pinned) + continue; + for (api = (*fpp)->api; *api != NULL; ++api) { + if ((*api)->used_mask & (*fpp)->value) { + fprintf(stderr, + "%s: pinned bit %#x for flag %s already in use\n", + progname, (*fpp)->value, (*fpp)->name); + return (1); + } + (*api)->used_mask |= (*fpp)->value; + } + } + /* * Here's the plan: walk the list of flags, allocating bits. For * each flag, we walk the list of APIs that use it and find a bit * none of them are using. That bit becomes the flag's value. */ for (fpp = flag_list; *fpp != NULL; ++fpp) { + if ((*fpp)->pinned) /* already assigned */ + continue; mask = 0xffffffff; /* Set to all 1's */ for (api = (*fpp)->api; *api != NULL; ++api) mask &= ~(*api)->used_mask; /* Clear API's bits */ diff --git a/lang/csharp/src/Internal/DbConstants.cs b/lang/csharp/src/Internal/DbConstants.cs index f333a8970..c25d813c4 100644 --- a/lang/csharp/src/Internal/DbConstants.cs +++ b/lang/csharp/src/Internal/DbConstants.cs @@ -158,19 +158,19 @@ internal class DbConstants { internal const uint DB_NEXT_DUP = 17; internal const uint DB_NEXT_NODUP = 18; internal const uint DB_NODUPDATA = 19; - internal const uint DB_NOLOCKING = 0x00004000; + internal const uint DB_NOLOCKING = 0x00002000; internal const uint DB_NOMMAP = 0x00000010; internal const uint DB_NOORDERCHK = 0x00000002; internal const uint DB_NOOVERWRITE = 20; - internal const uint DB_NOPANIC = 0x00008000; + internal const uint DB_NOPANIC = 0x00004000; internal const int DB_NOSERVER = -30989; internal const uint DB_NOSYNC = 0x00000001; internal const int DB_NOTFOUND = -30988; internal const int DB_OLD_VERSION = -30987; internal const uint DB_ORDERCHKONLY = 0x00000004; - internal const uint DB_OVERWRITE = 0x00010000; + internal const uint DB_OVERWRITE = 0x00008000; internal const int DB_PAGE_NOTFOUND = -30986; - internal const uint DB_PANIC_ENVIRONMENT = 0x00020000; + internal const uint DB_PANIC_ENVIRONMENT = 0x00010000; internal const uint DB_POSITION = 22; internal const uint DB_PREV = 23; internal const uint DB_PREV_DUP = 24; @@ -190,7 +190,7 @@ internal class DbConstants { internal const uint DB_RECNUM = 0x00000040; internal const uint DB_RECOVER = 0x00000002; internal const uint DB_RECOVER_FATAL = 0x00020000; - internal const uint DB_REGION_INIT = 0x00040000; + internal const uint DB_REGION_INIT = 0x00020000; internal const uint DB_REGISTER = 0x00040000; internal const uint DB_RENUMBER = 0x00000080; internal const int DB_REPMGR_ACKS_ALL = 1; @@ -265,7 +265,7 @@ internal class DbConstants { internal const uint DB_SYSTEM_MEM = 0x00080000; internal const uint DB_THREAD = 0x00000020; internal const int DB_TIMEOUT = -30971; - internal const uint DB_TIME_NOTGRANTED = 0x00080000; + internal const uint DB_TIME_NOTGRANTED = 0x00040000; internal const uint DB_TRUNCATE = 0x00020000; internal const uint DB_TXN_ABORT = 0; internal const uint DB_TXN_APPLY = 1; @@ -279,7 +279,7 @@ internal class DbConstants { internal const uint DB_TXN_SNAPSHOT = 0x00000004; internal const uint DB_TXN_SYNC = 0x00000008; internal const uint DB_TXN_TOKEN_SIZE = 20; - internal const uint DB_TXN_WAIT = 0x00000100; + internal const uint DB_TXN_WAIT = 0x00000080; internal const uint DB_TXN_WRITE_NOSYNC = 0x00000020; internal const uint DB_UNKNOWN = 5; internal const uint DB_UPGRADE = 0x00000001; @@ -318,7 +318,7 @@ internal class DbConstants { internal const string DB_VERSION_STRING = "Berkeley DB 5.3.29: September 9 2013 "; internal const string DB_VERSION_FULL_STRING = "Berkeley DB 11g Release 2 library version 11.2.5.3.29: September 9 2013 "; internal const uint DB_WRITECURSOR = 0x00000010; - internal const uint DB_YIELDCPU = 0x00100000; + internal const uint DB_YIELDCPU = 0x00080000; internal const uint DB_USERCOPY_GETDATA = 0x00000001; internal const uint DB_USERCOPY_SETDATA = 0x00000002; } diff --git a/lang/java/src/com/sleepycat/db/internal/DbConstants.java b/lang/java/src/com/sleepycat/db/internal/DbConstants.java index e89608ddd..19eb73e46 100644 --- a/lang/java/src/com/sleepycat/db/internal/DbConstants.java +++ b/lang/java/src/com/sleepycat/db/internal/DbConstants.java @@ -129,16 +129,16 @@ public interface DbConstants int DB_NEXT_DUP = 17; int DB_NEXT_NODUP = 18; int DB_NODUPDATA = 19; - int DB_NOLOCKING = 0x00004000; + int DB_NOLOCKING = 0x00002000; int DB_NOMMAP = 0x00000010; int DB_NOORDERCHK = 0x00000002; int DB_NOOVERWRITE = 20; - int DB_NOPANIC = 0x00008000; + int DB_NOPANIC = 0x00004000; int DB_NOSYNC = 0x00000001; int DB_NOTFOUND = -30988; int DB_ORDERCHKONLY = 0x00000004; - int DB_OVERWRITE = 0x00010000; - int DB_PANIC_ENVIRONMENT = 0x00020000; + int DB_OVERWRITE = 0x00008000; + int DB_PANIC_ENVIRONMENT = 0x00010000; int DB_POSITION = 22; int DB_PREV = 23; int DB_PREV_DUP = 24; @@ -158,7 +158,7 @@ public interface DbConstants int DB_RECNUM = 0x00000040; int DB_RECOVER = 0x00000002; int DB_RECOVER_FATAL = 0x00020000; - int DB_REGION_INIT = 0x00040000; + int DB_REGION_INIT = 0x00020000; int DB_REGISTER = 0x00040000; int DB_RENUMBER = 0x00000080; int DB_REPMGR_ACKS_ALL = 1; @@ -218,7 +218,7 @@ public interface DbConstants int DB_SYSTEM_MEM = 0x00080000; int DB_THREAD = 0x00000020; int DB_TIMEOUT = -30971; - int DB_TIME_NOTGRANTED = 0x00080000; + int DB_TIME_NOTGRANTED = 0x00040000; int DB_TRUNCATE = 0x00020000; int DB_TXN_ABORT = 0; int DB_TXN_APPLY = 1; @@ -232,7 +232,7 @@ public interface DbConstants int DB_TXN_SNAPSHOT = 0x00000004; int DB_TXN_SYNC = 0x00000008; int DB_TXN_TOKEN_SIZE = 20; - int DB_TXN_WAIT = 0x00000100; + int DB_TXN_WAIT = 0x00000080; int DB_TXN_WRITE_NOSYNC = 0x00000020; int DB_UNKNOWN = 5; int DB_UPGRADE = 0x00000001; @@ -260,7 +260,7 @@ public interface DbConstants int DB_VERSION_MINOR = 3; int DB_VERSION_PATCH = 29; int DB_WRITECURSOR = 0x00000010; - int DB_YIELDCPU = 0x00100000; + int DB_YIELDCPU = 0x00080000; } // end of DbConstants.java diff --git a/src/dbinc_auto/api_flags.in b/src/dbinc_auto/api_flags.in index 9c0e6c626..4546fe0d1 100644 --- a/src/dbinc_auto/api_flags.in +++ b/src/dbinc_auto/api_flags.in @@ -85,7 +85,7 @@ #define DB_LOG_VERIFY_WARNING 0x00000080 #define DB_LOG_WRNOSYNC 0x00000020 #define DB_LOG_ZERO 0x00000010 -#define DB_MPOOL_AIO 0x00001000 +#define DB_MPOOL_AIO 0x00100000 #define DB_MPOOL_CREATE 0x00000001 #define DB_MPOOL_DIRTY 0x00000002 #define DB_MPOOL_DISCARD 0x00000001 @@ -107,18 +107,18 @@ #define DB_MUTEX_SELF_BLOCK 0x00000010 #define DB_MUTEX_SHARED 0x00000020 #define DB_NOERROR 0x00004000 -#define DB_NOFLUSH 0x00002000 -#define DB_NOLOCKING 0x00004000 +#define DB_NOFLUSH 0x00001000 +#define DB_NOLOCKING 0x00002000 #define DB_NOMMAP 0x00000010 #define DB_NOORDERCHK 0x00000002 -#define DB_NOPANIC 0x00008000 +#define DB_NOPANIC 0x00004000 #define DB_NOSYNC 0x00000001 #define DB_NO_AUTO_COMMIT 0x00008000 #define DB_NO_CHECKPOINT 0x00008000 #define DB_ODDFILESIZE 0x00000080 #define DB_ORDERCHKONLY 0x00000004 -#define DB_OVERWRITE 0x00010000 -#define DB_PANIC_ENVIRONMENT 0x00020000 +#define DB_OVERWRITE 0x00008000 +#define DB_PANIC_ENVIRONMENT 0x00010000 #define DB_PRINTABLE 0x00000008 #define DB_PRIVATE 0x00010000 #define DB_PR_PAGE 0x00000010 @@ -130,7 +130,7 @@ #define DB_RECNUM 0x00000040 #define DB_RECOVER 0x00000002 #define DB_RECOVER_FATAL 0x00020000 -#define DB_REGION_INIT 0x00040000 +#define DB_REGION_INIT 0x00020000 #define DB_REGISTER 0x00040000 #define DB_RENUMBER 0x00000080 #define DB_REPMGR_CONF_2SITE_STRICT 0x00000001 @@ -188,7 +188,7 @@ #define DB_ST_TOPLEVEL 0x00010000 #define DB_SYSTEM_MEM 0x00080000 #define DB_THREAD 0x00000020 -#define DB_TIME_NOTGRANTED 0x00080000 +#define DB_TIME_NOTGRANTED 0x00040000 #define DB_TRUNCATE 0x00020000 #define DB_TXN_BULK 0x00000010 #define DB_TXN_FAMILY 0x00000040 @@ -196,9 +196,9 @@ #define DB_TXN_NOT_DURABLE 0x00000004 #define DB_TXN_NOWAIT 0x00000002 #define DB_TXN_SNAPSHOT 0x00000004 -#define DB_TXN_SNAPSHOT_SAFE 0x00000080 +#define DB_TXN_SNAPSHOT_SAFE 0x00000800 #define DB_TXN_SYNC 0x00000008 -#define DB_TXN_WAIT 0x00000100 +#define DB_TXN_WAIT 0x00000080 #define DB_TXN_WRITE_NOSYNC 0x00000020 #define DB_UNREF 0x00020000 #define DB_UPGRADE 0x00000001 @@ -227,4 +227,4 @@ #define DB_WRITELOCK 0x00000020 #define DB_WRITEOPEN 0x00040000 #define DB_XA_CREATE 0x00000001 -#define DB_YIELDCPU 0x00100000 +#define DB_YIELDCPU 0x00080000