From 884c38d6c4a733a5e0b397050f3ca08545780edd Mon Sep 17 00:00:00 2001 From: skidder Date: Sat, 18 Jan 2003 21:45:24 +0000 Subject: [PATCH] Memory manager changes - added memory usage stats, empty extents are now deallocated --- src/common/classes/alloc.cpp | 100 ++++-- src/common/classes/alloc.h | 30 +- src/common/classes/class_test.cpp | 2 +- src/common/classes/test.sh | 2 +- src/dsql/dsql.tab.h | 518 +++++++++++++++--------------- src/jrd/all.cpp | 25 ++ src/jrd/all.h | 10 +- src/jrd/inf.cpp | 10 + src/jrd/jrd.cpp | 8 +- src/jrd/jrd.h | 2 +- 10 files changed, 414 insertions(+), 293 deletions(-) diff --git a/src/common/classes/alloc.cpp b/src/common/classes/alloc.cpp index c12fd4ddfd..4e48eec549 100644 --- a/src/common/classes/alloc.cpp +++ b/src/common/classes/alloc.cpp @@ -54,6 +54,9 @@ namespace Firebird { +int process_max_memory = 0; +int process_current_memory = 0; + // Helper function to reduce code size, since many compilers // generate quite a bit of code at the point of the throw. static void pool_out_of_memory() @@ -227,7 +230,7 @@ void MemoryPool::print_contents(IB_FILE *file, bool used_only) { lock.leave(); } -MemoryPool* MemoryPool::internal_create(size_t instance_size) { +MemoryPool* MemoryPool::internal_create(size_t instance_size, int *cur_mem, int *max_mem) { size_t alloc_size = FB_MAX( // This is the exact initial layout of memory pool in the first extent // MEM_ALIGN(sizeof(MemoryExtent)) + @@ -250,8 +253,11 @@ MemoryPool* MemoryPool::internal_create(size_t instance_size) { MEM_ALIGN(sizeof(MemoryExtent)) + MEM_ALIGN(sizeof(MemoryBlock)) + MEM_ALIGN(instance_size) + - MEM_ALIGN(sizeof(MemoryBlock))); - + MEM_ALIGN(sizeof(MemoryBlock)), + cur_mem, max_mem); + + pool->extents_memory = alloc_size - MEM_ALIGN(sizeof(MemoryExtent)); + MemoryBlock *poolBlk = (MemoryBlock*) (mem+MEM_ALIGN(sizeof(MemoryExtent))); poolBlk->pool = pool; poolBlk->used = true; @@ -301,11 +307,14 @@ void MemoryPool::deletePool(MemoryPool* pool) { 2. The lock is copied before the extent that contains the pool itself is freed, because otherwise it contains garbage. The lock will be destroyed automatically at exit. */ + /* skidder: Working with a copy of spinlock or critical section is not + a correct operation. We simply need to delete object earlier */ #ifdef SUPERSERVER - Spinlock lock = pool->lock; + pool->lock.~Spinlock(); #else - SharedSpinlock lock = pool->lock; + pool->lock.~SharedSpinlock(); #endif + if (pool->cur_memory) *pool->cur_memory -= pool->used_memory; // Delete all extents now MemoryExtent *temp = pool->extents; while (temp) { @@ -323,25 +332,25 @@ void* MemoryPool::internal_alloc(size_t size, SSHORT type // Lookup a block greater or equal than size in freeBlocks tree size = MEM_ALIGN(size); BlockInfo temp = {NULL, size}; - void *result; + MemoryBlock* blk; if (freeBlocks.locate(locGreatEqual,temp)) { // Found large enough block BlockInfo* current = &freeBlocks.current(); if (current->length-size < MEM_ALIGN(sizeof(MemoryBlock))+ALLOC_ALIGNMENT) { + blk = current->block; // Block is small enough to be returned AS IS - current->block->used = true; - current->block->type = type; + blk->used = true; + blk->type = type; #ifdef DEBUG_GDS_ALLOC - current->block->file = file; - current->block->line = line; + blk->file = file; + blk->line = line; #endif - result = (char *)current->block + MEM_ALIGN(sizeof(MemoryBlock)); freeBlocks.fastRemove(); } else { // Cut a piece at the end of block in hope to avoid structural // modification of free blocks tree current->block->length -= MEM_ALIGN(sizeof(MemoryBlock))+size; - MemoryBlock *blk = (MemoryBlock *)((char*)current->block + + blk = (MemoryBlock *)((char*)current->block + MEM_ALIGN(sizeof(MemoryBlock)) + current->block->length); blk->pool = this; blk->used = true; @@ -372,7 +381,6 @@ void* MemoryPool::internal_alloc(size_t size, SSHORT type freeBlocks.fastRemove(); addFreeBlock(block); } - result = (char*)blk+MEM_ALIGN(sizeof(MemoryBlock)); } } else { // If we are in a critically low memory condition look up for a block in a list @@ -394,6 +402,14 @@ void* MemoryPool::internal_alloc(size_t size, SSHORT type prev->next = itr->next; else pendingFree = itr->next; + // We can do this w/o any locking because + // (1) -= integer operation is atomic on all current platforms + // (2) nobody will die if max_memory will be a little inprecise + used_memory += temp->length + MEM_ALIGN(sizeof(MemoryBlock)); + if (cur_memory) { + *cur_memory += temp->length + MEM_ALIGN(sizeof(MemoryBlock)); + if (max_memory && *max_memory < *cur_memory) *max_memory = *cur_memory; + } PATTERN_FILL(itr,size,ALLOC_PATTERN); return itr; } else { @@ -401,7 +417,7 @@ void* MemoryPool::internal_alloc(size_t size, SSHORT type // We don't need to modify tree of free blocks or a list of // pending free blocks in this case temp->length -= MEM_ALIGN(sizeof(MemoryBlock))+size; - MemoryBlock *blk = (MemoryBlock *)((char*)temp + + blk = (MemoryBlock *)((char*)temp + MEM_ALIGN(sizeof(MemoryBlock)) + temp->length); blk->pool = this; blk->used = true; @@ -416,7 +432,12 @@ void* MemoryPool::internal_alloc(size_t size, SSHORT type blk->prev = temp; if (!blk->last) ((MemoryBlock *)((char*)blk + MEM_ALIGN(sizeof(MemoryBlock)) + blk->length))->prev = blk; - result = (char *)blk + MEM_ALIGN(sizeof(MemoryBlock)); + used_memory += blk->length + MEM_ALIGN(sizeof(MemoryBlock)); + if (cur_memory) { + *cur_memory += blk->length + MEM_ALIGN(sizeof(MemoryBlock)); + if (max_memory && *max_memory < *cur_memory) *max_memory = *cur_memory; + } + void *result = (char *)blk + MEM_ALIGN(sizeof(MemoryBlock)); PATTERN_FILL(result,size,ALLOC_PATTERN); return result; } @@ -430,10 +451,11 @@ void* MemoryPool::internal_alloc(size_t size, SSHORT type if (!extent) { return NULL; } + extents_memory += alloc_size - MEM_ALIGN(sizeof(MemoryExtent)); extent->next = extents; extents = extent; - MemoryBlock *blk = (MemoryBlock *)((char*)extent+MEM_ALIGN(sizeof(MemoryExtent))); + blk = (MemoryBlock *)((char*)extent+MEM_ALIGN(sizeof(MemoryExtent))); blk->pool = this; blk->used = true; blk->type = type; @@ -460,8 +482,13 @@ void* MemoryPool::internal_alloc(size_t size, SSHORT type rest->prev = blk; addFreeBlock(rest); } - result = (char*)blk+MEM_ALIGN(sizeof(MemoryBlock)); } + used_memory += blk->length + MEM_ALIGN(sizeof(MemoryBlock)); + if (cur_memory) { + *cur_memory += blk->length + MEM_ALIGN(sizeof(MemoryBlock)); + if (max_memory && *max_memory < *cur_memory) *max_memory = *cur_memory; + } + void *result = (char*)blk+MEM_ALIGN(sizeof(MemoryBlock)); // Grow spare blocks pool if necessary PATTERN_FILL(result,size,ALLOC_PATTERN); return result; @@ -506,12 +533,35 @@ void MemoryPool::removeFreeBlock(MemoryBlock *blk) { } } +void MemoryPool::free_blk_extent(MemoryBlock *blk) { + MemoryExtent *extent = (MemoryExtent *)((char *)blk-MEM_ALIGN(sizeof(MemoryExtent))); + MemoryExtent *itr = extents; + if (extents == extent) + extents = extents->next; + else + { + while ( itr ) { + MemoryExtent *next = itr->next; + if (next==extent) { + itr->next = extent->next; + break; + } + itr = next; + } + assert(itr); // We had to find it somewhere + } + extents_memory -= blk->length + MEM_ALIGN(sizeof(MemoryBlock)); + external_free(extent); +} + void MemoryPool::deallocate(void *block) { if (!block) return; lock.enter(); MemoryBlock *blk = (MemoryBlock *)((char*)block - MEM_ALIGN(sizeof(MemoryBlock))), *prev; assert(blk->used); assert(blk->pool==this); + used_memory -= blk->length + MEM_ALIGN(sizeof(MemoryBlock)); + if (cur_memory) *cur_memory -= blk->length + MEM_ALIGN(sizeof(MemoryBlock)); // Try to merge block with preceding free block if ((prev = blk->prev) && !prev->used) { removeFreeBlock(prev); @@ -535,7 +585,10 @@ void MemoryPool::deallocate(void *block) { } } PATTERN_FILL((char*)prev+MEM_ALIGN(sizeof(MemoryBlock)),prev->length,FREE_PATTERN); - addFreeBlock(prev); + if (!prev->prev && prev->last) + free_blk_extent(prev); + else + addFreeBlock(prev); } else { MemoryBlock *next; // Mark block as free @@ -550,8 +603,11 @@ void MemoryPool::deallocate(void *block) { if (!next->last) ((MemoryBlock *)((char *)next+MEM_ALIGN(sizeof(MemoryBlock))+next->length))->prev = blk; } - PATTERN_FILL((char*)blk+MEM_ALIGN(sizeof(MemoryBlock)),blk->length,FREE_PATTERN); - addFreeBlock(blk); + PATTERN_FILL(block,blk->length,FREE_PATTERN); + if (!blk->prev && blk->last) + free_blk_extent(blk); + else + addFreeBlock(blk); } if (needSpare) updateSpare(); lock.leave(); @@ -559,13 +615,13 @@ void MemoryPool::deallocate(void *block) { } /* namespace Firebird */ +#ifndef TESTING_ONLY + Firebird::MemoryPool* getDefaultMemoryPool() { if (!Firebird::processMemoryPool) Firebird::processMemoryPool = MemoryPool::createPool(); return Firebird::processMemoryPool; } -#ifndef TESTING_ONLY - extern "C" { #ifdef DEBUG_GDS_ALLOC diff --git a/src/common/classes/alloc.h b/src/common/classes/alloc.h index 496b2dad7e..5013bce3ee 100644 --- a/src/common/classes/alloc.h +++ b/src/common/classes/alloc.h @@ -81,11 +81,17 @@ struct PendingFreeBlock { PendingFreeBlock *next; }; +extern int process_current_memory, process_max_memory; + // Memory pool based on B+ tree of free memory blocks // We are going to have two target architectures: // 1. Multi-process server with customizable lock manager // 2. Multi-threaded server with single process (SUPERSERVER) +// +// MemoryPool inheritance looks weird because we cannot use +// any pointers to functions in shared memory. VMT usage in +// MemoryPool and its descendants is prohibited class MemoryPool { private: class InternalAllocator { @@ -111,6 +117,8 @@ private: #else SharedSpinlock lock; #endif + int extents_memory; // Sum of memory in allocated extents minus size of extents headers + int used_memory; // Size of used memory blocks including block headers /* Returns NULL in case it cannot allocate requested chunk */ static void* external_alloc(size_t size); @@ -127,6 +135,8 @@ private: void removeFreeBlock(MemoryBlock *blk); + void free_blk_extent(MemoryBlock *blk); + // does all the stuff except locking and exceptions void* internal_alloc(size_t size, SSHORT type = 0 #ifdef DEBUG_GDS_ALLOC @@ -134,12 +144,18 @@ private: #endif ); protected: + int *cur_memory; + int *max_memory; // Do not allow to create and destroy pool directly from outside - MemoryPool(void *first_extent, void *root_page) : + MemoryPool(void *first_extent, void *root_page, int* cur_mem = NULL, int* max_mem = NULL) : freeBlocks((InternalAllocator*)this, root_page), extents((MemoryExtent *)first_extent), needSpare(false), - pendingFree(NULL) + pendingFree(NULL), + /*extents_memory(0), - Initialized in internal_create() */ + used_memory(0), + cur_memory(cur_mem), + max_memory(max_mem) { } @@ -147,8 +163,16 @@ protected: ~MemoryPool() { } - static MemoryPool* internal_create(size_t instance_size); + static MemoryPool* internal_create(size_t instance_size, + int *cur_mem = &process_current_memory, int *max_mem = &process_max_memory); public: + // Move usage stats to another location + void moveStats(int *cur_mem, int *max_mem) { + *cur_mem = *cur_memory; + *max_mem = *max_memory; + cur_memory = cur_mem; + max_memory = max_mem; + } static MemoryPool* createPool() { return internal_create(sizeof(MemoryPool)); } diff --git a/src/common/classes/class_test.cpp b/src/common/classes/class_test.cpp index e494fa2a06..2661d6070c 100644 --- a/src/common/classes/class_test.cpp +++ b/src/common/classes/class_test.cpp @@ -312,7 +312,7 @@ void testAllocator() { } while (bigItems.getNext()); printf(" DONE\n"); pool->verify_pool(); - pool->print_pool(stdout,true); + pool->print_contents(stdout,true); MemoryPool::deletePool(pool); // TODO: // Test critically low memory conditions diff --git a/src/common/classes/test.sh b/src/common/classes/test.sh index 8fcb0ceaa4..f9a6cc795b 100755 --- a/src/common/classes/test.sh +++ b/src/common/classes/test.sh @@ -1,7 +1,7 @@ # Test for library integrity # this should be compiled with optimization turned off and with NDEBUG undefined ulimit -s unlimited -g++ -ggdb -Wall -I../../include -DDEBUG_GDS_ALLOC class_test.cpp alloc.cpp ../fb_exception.cpp 2> aa +g++ -ggdb -Wall -I../../include -DTESTING_ONLY -DDEBUG_GDS_ALLOC class_test.cpp alloc.cpp ../fb_exception.cpp 2> aa ./a.out # Chose the best algorithm parameters for the target architecture diff --git a/src/dsql/dsql.tab.h b/src/dsql/dsql.tab.h index 778c924ae7..fd57a0b1a1 100644 --- a/src/dsql/dsql.tab.h +++ b/src/dsql/dsql.tab.h @@ -1,256 +1,262 @@ -#define ACTIVE 257 -#define ADD 258 -#define AFTER 259 -#define ALL 260 -#define ALTER 261 -#define AND 262 -#define ANY 263 -#define AS 264 -#define ASC 265 -#define AT 266 -#define AVG 267 -#define AUTO 268 -#define BASENAME 269 -#define BEFORE 270 -#define BEGIN 271 -#define BETWEEN 272 -#define BLOB 273 -#define BY 274 -#define CACHE 275 -#define CAST 276 -#define CHARACTER 277 -#define CHECK 278 -#define CHECK_POINT_LEN 279 -#define COLLATE 280 -#define COLLATION 281 -#define COMMA 282 -#define COMMIT 283 -#define COMMITTED 284 -#define COMPUTED 285 -#define CONCATENATE 286 -#define CONDITIONAL 287 -#define CONSTRAINT 288 -#define CONTAINING 289 -#define COUNT 290 -#define CREATE 291 -#define CSTRING 292 -#define CURRENT 293 -#define CURSOR 294 -#define DATABASE 295 -#define DATE 296 -#define DB_KEY 297 -#define KW_DEBUG 298 -#define DECIMAL 299 -#define DECLARE 300 -#define DEFAULT 301 -#define DELETE 302 -#define DESC 303 -#define DISTINCT 304 -#define DO 305 -#define DOMAIN 306 -#define DROP 307 -#define ELSE 308 -#define END 309 -#define ENTRY_POINT 310 -#define EQL 311 -#define ESCAPE 312 -#define EXCEPTION 313 -#define EXECUTE 314 -#define EXISTS 315 -#define EXIT 316 -#define EXTERNAL 317 -#define FILTER 318 -#define FOR 319 -#define FOREIGN 320 -#define FROM 321 -#define FULL 322 -#define FUNCTION 323 -#define GDSCODE 324 -#define GEQ 325 -#define GENERATOR 326 -#define GEN_ID 327 -#define GRANT 328 -#define GROUP 329 -#define GROUP_COMMIT_WAIT 330 -#define GTR 331 -#define HAVING 332 -#define IF 333 -#define IN 334 -#define INACTIVE 335 -#define INNER 336 -#define INPUT_TYPE 337 -#define INDEX 338 -#define INSERT 339 -#define INTEGER 340 -#define INTO 341 -#define IS 342 -#define ISOLATION 343 -#define JOIN 344 -#define KEY 345 -#define KW_CHAR 346 -#define KW_DEC 347 -#define KW_DOUBLE 348 -#define KW_FILE 349 -#define KW_FLOAT 350 -#define KW_INT 351 -#define KW_LONG 352 -#define KW_NULL 353 -#define KW_NUMERIC 354 -#define KW_UPPER 355 -#define KW_VALUE 356 -#define LENGTH 357 -#define LOGFILE 358 -#define LPAREN 359 -#define LEFT 360 -#define LEQ 361 -#define LEVEL 362 -#define LIKE 363 -#define LOG_BUF_SIZE 364 -#define LSS 365 -#define MANUAL 366 -#define MAXIMUM 367 -#define MAX_SEGMENT 368 -#define MERGE 369 -#define MESSAGE 370 -#define MINIMUM 371 -#define MODULE_NAME 372 -#define NAMES 373 -#define NATIONAL 374 -#define NATURAL 375 -#define NCHAR 376 -#define NEQ 377 -#define NO 378 -#define NOT 379 -#define NOT_GTR 380 -#define NOT_LSS 381 -#define NUM_LOG_BUFS 382 -#define OF 383 -#define ON 384 -#define ONLY 385 -#define OPTION 386 -#define OR 387 -#define ORDER 388 -#define OUTER 389 -#define OUTPUT_TYPE 390 -#define OVERFLOW 391 -#define PAGE 392 -#define PAGES 393 -#define PAGE_SIZE 394 -#define PARAMETER 395 -#define PASSWORD 396 -#define PLAN 397 -#define POSITION 398 -#define POST_EVENT 399 -#define PRECISION 400 -#define PRIMARY 401 -#define PRIVILEGES 402 -#define PROCEDURE 403 -#define PROTECTED 404 -#define RAW_PARTITIONS 405 -#define READ 406 -#define REAL 407 -#define REFERENCES 408 -#define RESERVING 409 -#define RETAIN 410 -#define RETURNING_VALUES 411 -#define RETURNS 412 -#define REVOKE 413 -#define RIGHT 414 -#define RPAREN 415 -#define ROLLBACK 416 -#define SEGMENT 417 -#define SELECT 418 -#define SET 419 -#define SHADOW 420 -#define SHARED 421 -#define SINGULAR 422 -#define SIZE 423 -#define SMALLINT 424 -#define SNAPSHOT 425 -#define SOME 426 -#define SORT 427 -#define SQLCODE 428 -#define STABILITY 429 -#define STARTING 430 -#define STATISTICS 431 -#define SUB_TYPE 432 -#define SUSPEND 433 -#define SUM 434 -#define TABLE 435 -#define THEN 436 -#define TO 437 -#define TRANSACTION 438 -#define TRIGGER 439 -#define UNCOMMITTED 440 -#define UNION 441 -#define UNIQUE 442 -#define UPDATE 443 -#define USER 444 -#define VALUES 445 -#define VARCHAR 446 -#define VARIABLE 447 -#define VARYING 448 -#define VERSION 449 -#define VIEW 450 -#define WAIT 451 -#define WHEN 452 -#define WHERE 453 -#define WHILE 454 -#define WITH 455 -#define WORK 456 -#define WRITE 457 -#define FLOAT 458 -#define NUMBER 459 -#define NUMERIC 460 -#define SYMBOL 461 -#define STRING 462 -#define INTRODUCER 463 -#define ACTION 464 -#define ADMIN 465 -#define CASCADE 466 -#define FREE_IT 467 -#define RESTRICT 468 -#define ROLE 469 -#define COLUMN 470 -#define TYPE 471 -#define EXTRACT 472 -#define YEAR 473 -#define MONTH 474 -#define DAY 475 -#define HOUR 476 -#define MINUTE 477 -#define SECOND 478 -#define WEEKDAY 479 -#define YEARDAY 480 -#define TIME 481 -#define TIMESTAMP 482 -#define CURRENT_DATE 483 -#define CURRENT_TIME 484 -#define CURRENT_TIMESTAMP 485 -#define NUMBER64BIT 486 -#define SCALEDINT 487 -#define CURRENT_USER 488 -#define CURRENT_ROLE 489 -#define KW_BREAK 490 -#define SUBSTRING 491 -#define RECREATE 492 -#define KW_DESCRIPTOR 493 -#define FIRST 494 -#define SKIP 495 -#define CONNECTION_ID 496 -#define TRANSACTION_ID 497 -#define BIGINT 498 -#define CASE 499 -#define NULLIF 500 -#define COALESCE 501 -#define USING 502 -#define NULLS 503 -#define LAST 504 -#define ROWS_AFFECTED 505 -#define LOCK 506 -#define SAVEPOINT 507 -#define STATEMENT 508 -#define LEAVE 509 -#define INSERTING 510 -#define UPDATING 511 -#define DELETING 512 +#ifndef YYSTYPE +#define YYSTYPE int +#endif +#define ACTIVE 257 +#define ADD 258 +#define AFTER 259 +#define ALL 260 +#define ALTER 261 +#define AND 262 +#define ANY 263 +#define AS 264 +#define ASC 265 +#define AT 266 +#define AVG 267 +#define AUTO 268 +#define BASENAME 269 +#define BEFORE 270 +#define BEGIN 271 +#define BETWEEN 272 +#define BLOB 273 +#define BY 274 +#define CACHE 275 +#define CAST 276 +#define CHARACTER 277 +#define CHECK 278 +#define CHECK_POINT_LEN 279 +#define COLLATE 280 +#define COLLATION 281 +#define COMMA 282 +#define COMMIT 283 +#define COMMITTED 284 +#define COMPUTED 285 +#define CONCATENATE 286 +#define CONDITIONAL 287 +#define CONSTRAINT 288 +#define CONTAINING 289 +#define COUNT 290 +#define CREATE 291 +#define CSTRING 292 +#define CURRENT 293 +#define CURSOR 294 +#define DATABASE 295 +#define DATE 296 +#define DB_KEY 297 +#define KW_DEBUG 298 +#define DECIMAL 299 +#define DECLARE 300 +#define DEFAULT 301 +#define DELETE 302 +#define DESC 303 +#define DISTINCT 304 +#define DO 305 +#define DOMAIN 306 +#define DROP 307 +#define ELSE 308 +#define END 309 +#define ENTRY_POINT 310 +#define EQL 311 +#define ESCAPE 312 +#define EXCEPTION 313 +#define EXECUTE 314 +#define EXISTS 315 +#define EXIT 316 +#define EXTERNAL 317 +#define FILTER 318 +#define FOR 319 +#define FOREIGN 320 +#define FROM 321 +#define FULL 322 +#define FUNCTION 323 +#define GDSCODE 324 +#define GEQ 325 +#define GENERATOR 326 +#define GEN_ID 327 +#define GRANT 328 +#define GROUP 329 +#define GROUP_COMMIT_WAIT 330 +#define GTR 331 +#define HAVING 332 +#define IF 333 +#define IN 334 +#define INACTIVE 335 +#define INNER 336 +#define INPUT_TYPE 337 +#define INDEX 338 +#define INSERT 339 +#define INTEGER 340 +#define INTO 341 +#define IS 342 +#define ISOLATION 343 +#define JOIN 344 +#define KEY 345 +#define KW_CHAR 346 +#define KW_DEC 347 +#define KW_DOUBLE 348 +#define KW_FILE 349 +#define KW_FLOAT 350 +#define KW_INT 351 +#define KW_LONG 352 +#define KW_NULL 353 +#define KW_NUMERIC 354 +#define KW_UPPER 355 +#define KW_VALUE 356 +#define LENGTH 357 +#define LOGFILE 358 +#define LPAREN 359 +#define LEFT 360 +#define LEQ 361 +#define LEVEL 362 +#define LIKE 363 +#define LOG_BUF_SIZE 364 +#define LSS 365 +#define MANUAL 366 +#define MAXIMUM 367 +#define MAX_SEGMENT 368 +#define MERGE 369 +#define MESSAGE 370 +#define MINIMUM 371 +#define MODULE_NAME 372 +#define NAMES 373 +#define NATIONAL 374 +#define NATURAL 375 +#define NCHAR 376 +#define NEQ 377 +#define NO 378 +#define NOT 379 +#define NOT_GTR 380 +#define NOT_LSS 381 +#define NUM_LOG_BUFS 382 +#define OF 383 +#define ON 384 +#define ONLY 385 +#define OPTION 386 +#define OR 387 +#define ORDER 388 +#define OUTER 389 +#define OUTPUT_TYPE 390 +#define OVERFLOW 391 +#define PAGE 392 +#define PAGES 393 +#define PAGE_SIZE 394 +#define PARAMETER 395 +#define PASSWORD 396 +#define PLAN 397 +#define POSITION 398 +#define POST_EVENT 399 +#define PRECISION 400 +#define PRIMARY 401 +#define PRIVILEGES 402 +#define PROCEDURE 403 +#define PROTECTED 404 +#define RAW_PARTITIONS 405 +#define READ 406 +#define REAL 407 +#define REFERENCES 408 +#define RESERVING 409 +#define RETAIN 410 +#define RETURNING_VALUES 411 +#define RETURNS 412 +#define REVOKE 413 +#define RIGHT 414 +#define RPAREN 415 +#define ROLLBACK 416 +#define SEGMENT 417 +#define SELECT 418 +#define SET 419 +#define SHADOW 420 +#define SHARED 421 +#define SINGULAR 422 +#define SIZE 423 +#define SMALLINT 424 +#define SNAPSHOT 425 +#define SOME 426 +#define SORT 427 +#define SQLCODE 428 +#define STABILITY 429 +#define STARTING 430 +#define STATISTICS 431 +#define SUB_TYPE 432 +#define SUSPEND 433 +#define SUM 434 +#define TABLE 435 +#define THEN 436 +#define TO 437 +#define TRANSACTION 438 +#define TRIGGER 439 +#define UNCOMMITTED 440 +#define UNION 441 +#define UNIQUE 442 +#define UPDATE 443 +#define USER 444 +#define VALUES 445 +#define VARCHAR 446 +#define VARIABLE 447 +#define VARYING 448 +#define VERSION 449 +#define VIEW 450 +#define WAIT 451 +#define WHEN 452 +#define WHERE 453 +#define WHILE 454 +#define WITH 455 +#define WORK 456 +#define WRITE 457 +#define FLOAT 458 +#define NUMBER 459 +#define NUMERIC 460 +#define SYMBOL 461 +#define STRING 462 +#define INTRODUCER 463 +#define ACTION 464 +#define ADMIN 465 +#define CASCADE 466 +#define FREE_IT 467 +#define RESTRICT 468 +#define ROLE 469 +#define COLUMN 470 +#define TYPE 471 +#define EXTRACT 472 +#define YEAR 473 +#define MONTH 474 +#define DAY 475 +#define HOUR 476 +#define MINUTE 477 +#define SECOND 478 +#define WEEKDAY 479 +#define YEARDAY 480 +#define TIME 481 +#define TIMESTAMP 482 +#define CURRENT_DATE 483 +#define CURRENT_TIME 484 +#define CURRENT_TIMESTAMP 485 +#define NUMBER64BIT 486 +#define SCALEDINT 487 +#define CURRENT_USER 488 +#define CURRENT_ROLE 489 +#define KW_BREAK 490 +#define SUBSTRING 491 +#define RECREATE 492 +#define KW_DESCRIPTOR 493 +#define FIRST 494 +#define SKIP 495 +#define CONNECTION_ID 496 +#define TRANSACTION_ID 497 +#define BIGINT 498 +#define CASE 499 +#define NULLIF 500 +#define COALESCE 501 +#define USING 502 +#define NULLS 503 +#define LAST 504 +#define ROWS_AFFECTED 505 +#define LOCK 506 +#define SAVEPOINT 507 +#define STATEMENT 508 +#define LEAVE 509 +#define INSERTING 510 +#define UPDATING 511 +#define DELETING 512 + + +extern YYSTYPE yylval; diff --git a/src/jrd/all.cpp b/src/jrd/all.cpp index 5ba79ead07..2d1cacb1cd 100644 --- a/src/jrd/all.cpp +++ b/src/jrd/all.cpp @@ -101,6 +101,31 @@ void ALL_check_memory() #endif /* DEV_BUILD */ +JrdMemoryPool *JrdMemoryPool::createPool(int *cur_mem, int *max_mem) { + JrdMemoryPool *result = (JrdMemoryPool *)internal_create(sizeof(JrdMemoryPool), + cur_mem, max_mem); + result->plb_buckets = NULL; + result->plb_segments = NULL; + result->plb_dccs = NULL; + new (&result->lls_cache) BlockCache (*result); + return result; +} + +JrdMemoryPool *JrdMemoryPool::createPool() { +#ifdef SUPERSERVER + DBB dbb = GET_DBB; + JrdMemoryPool *result = (JrdMemoryPool *)internal_create(sizeof(JrdMemoryPool), + (int*)&dbb->dbb_current_memory, (int*)&dbb->dbb_max_memory); +#else + JrdMemoryPool *result = (JrdMemoryPool *)internal_create(sizeof(JrdMemoryPool)); +#endif + result->plb_buckets = NULL; + result->plb_segments = NULL; + result->plb_dccs = NULL; + new (&result->lls_cache) BlockCache (*result); + return result; +} + TEXT* ALL_cstring(TEXT* in_string) { /************************************** diff --git a/src/jrd/all.h b/src/jrd/all.h index b9f3c2f84e..12b66ddba2 100644 --- a/src/jrd/all.h +++ b/src/jrd/all.h @@ -47,14 +47,8 @@ protected: JrdMemoryPool() : MemoryPool(NULL, NULL), lls_cache(*this) {} ~JrdMemoryPool() {} public: - static JrdMemoryPool *createPool() { - JrdMemoryPool *result = (JrdMemoryPool *)internal_create(sizeof(JrdMemoryPool)); - result->plb_buckets = NULL; - result->plb_segments = NULL; - result->plb_dccs = NULL; - new (&result->lls_cache) BlockCache (*result); - return result; - } + static JrdMemoryPool *createPool(int *cur_mem, int *max_mem); + static JrdMemoryPool *createPool(); static void deletePool(JrdMemoryPool* pool) { pool->lls_cache.~BlockCache(); MemoryPool::deletePool(pool); diff --git a/src/jrd/inf.cpp b/src/jrd/inf.cpp index 6b7b43e8ad..7ceb161ee9 100644 --- a/src/jrd/inf.cpp +++ b/src/jrd/inf.cpp @@ -383,6 +383,7 @@ int INF_database_info( length = 0; break; +#ifdef SUPERSERVER case isc_info_current_memory: length = INF_convert(dbb->dbb_current_memory, buffer); break; @@ -390,6 +391,15 @@ int INF_database_info( case isc_info_max_memory: length = INF_convert(dbb->dbb_max_memory, buffer); break; +#else + case isc_info_current_memory: + length = INF_convert(process_current_memory, buffer); + break; + + case isc_info_max_memory: + length = INF_convert(process_max_memory, buffer); + break; +#endif case isc_info_attachment_id: length = INF_convert(PAG_attachment_id(), buffer); diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index d70f897ab7..de2b6c4fec 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -5621,9 +5621,15 @@ static DBB init(TDBB tdbb, tdbb->tdbb_database = 0; try { - +#ifdef SUPERSERVER + int cur_perm = 0, max_perm = 0; + JrdMemoryPool* perm = JrdMemoryPool::createPool(&cur_perm, &max_perm); + dbb_ = dbb::newDbb(*perm); + perm->moveStats((int*)&dbb_->dbb_current_memory, (int*)&dbb_->dbb_max_memory); +#else JrdMemoryPool* perm = JrdMemoryPool::createPool(); dbb_ = dbb::newDbb(*perm); +#endif //temp.blk_type = type_dbb; dbb_->dbb_permanent = perm; dbb_->dbb_mutexes = temp_mutx; diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h index 3d0a7fb5da..4a4ab1a73c 100644 --- a/src/jrd/jrd.h +++ b/src/jrd/jrd.h @@ -113,7 +113,7 @@ class tdbb; class dbb : private pool_alloc { public: - static dbb* newDbb(MemoryPool& p) { + static dbb* newDbb(MemoryPool& p) { return FB_NEW(p) dbb(p); }