open-source-search-engine/Mem.h

319 lines
11 KiB
C
Raw Normal View History

2013-08-03 00:12:24 +04:00
// Matt Wells, copyright Sep 2001
// . mostly just wrappers for most memory functions
// . allows us to constrain memory
// . also calls mlockall() on construction to avoid swapping out any mem
// . TODO: primealloc(int slotSize,int numSlots) :
// pre-allocs a table of these slots for faster mmalloc'ing
#ifndef _MEM_H_
#define _MEM_H_
#include <sys/mman.h> // mlockall
#include <netinet/in.h> // for htonll
#include "Conf.h"
#include <new>
//#ifdef DMALLOC
//#include <dmalloc.h>
//#endif
extern bool g_inMemFunction;
2013-08-03 00:12:24 +04:00
// we share malloc between threads, so you need to get the lock
//void mutexLock ( );
//void mutexUnlock ( );
class SafeBuf;
2013-08-03 00:12:24 +04:00
// some memory manipulation functions inlined below
2014-10-30 22:36:39 +03:00
int64_t htonll ( uint64_t a );
int64_t ntohll ( uint64_t a );
2013-08-03 00:12:24 +04:00
key_t ntohkey ( key_t key ) ;
key_t htonkey ( key_t key ) ;
/*
2014-11-11 01:45:11 +03:00
int32_t getNumBitsOn ( unsigned char bits );
int32_t getNumBitsOn ( uint16_t bits );
int32_t getNumBitsOn ( uint32_t bits );
int32_t getNumBitsOn ( uint64_t bits );
2013-08-03 00:12:24 +04:00
*/
// assume only one bit is set for this (used by Address.cpp)
2014-11-11 01:45:11 +03:00
int32_t getBitPosLL ( uint8_t *bit );
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
int32_t getHighestLitBit ( unsigned char bits ) ;
int32_t getHighestLitBit ( uint16_t bits ) ;
2013-08-03 00:12:24 +04:00
2014-10-30 22:36:39 +03:00
// these are bit #'s, like 0,1,2,3,...63 for int64_ts
2014-11-11 01:45:11 +03:00
int32_t getLowestLitBitLL ( uint64_t bits ) ;
2013-08-03 00:12:24 +04:00
// this is the value, like 0,1,2,4, ... 4billion
2014-11-11 01:45:11 +03:00
uint32_t getHighestLitBitValue ( uint32_t bits ) ;
uint64_t getHighestLitBitValueLL ( uint64_t bits ) ;
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
uint32_t reverseBits ( uint32_t x ) ;
2013-08-03 00:12:24 +04:00
// async signal safe functions
2015-01-15 01:12:55 +03:00
//void memcpy_ass ( register void *dest , register const void *src , int32_t len ) ;
2014-11-11 01:45:11 +03:00
void memset_ass ( register void *dst , register const char c , int32_t len ) ;
void memset_nice ( register void *dst , register const char c , int32_t len ,
int32_t niceness ) ;
2013-08-03 00:12:24 +04:00
// . "*Bits" is bit offset in *
// . nb is the # of bits to compare or copy
// . returns -1 if dst < src, 0 if equal, +1 if dst > src
// . bit #0 is the least significant bit on this little endian machine
// . TODO: should we speed this up?
2014-11-11 01:45:11 +03:00
int32_t membitcmp ( void *dst, int32_t dstBits, void *src, int32_t srcBits, int32_t nb );
2013-08-03 00:12:24 +04:00
// like above byt returns # of bits in common
2014-11-11 01:45:11 +03:00
int32_t membitcmp2 ( void *dst, int32_t dstBits, void *src, int32_t srcBits, int32_t nb );
2013-08-03 00:12:24 +04:00
// two bit copies, membitcpy1 starts copying at low bit, 2 at high bit
2014-11-11 01:45:11 +03:00
void membitcpy1 ( void *dst, int32_t dstBits, void *src, int32_t srcBits, int32_t nb );
void membitcpy2 ( void *dst, int32_t dstBits, void *src, int32_t srcBits, int32_t nb );
2013-08-03 00:12:24 +04:00
inline int gbstrlen ( const char *s ) {
if ( ! s ) { char *xx=NULL;*xx=0; }
return strlen(s);
};
class Mem {
public:
Mem();
~Mem();
bool init ( );//int64_t maxMem );
2013-08-03 00:12:24 +04:00
void setPid();
pid_t getPid();
void *gbmalloc ( int size , const char *note );
void *gbcalloc ( int size , const char *note);
void *gbrealloc ( void *oldPtr, int oldSize, int newSize,
const char *note);
void gbfree ( void *ptr , int size , const char *note);
2014-11-11 01:45:11 +03:00
char *dup ( const void *data , int32_t dataSize , const char *note);
2013-08-03 00:12:24 +04:00
char *strdup ( const char *string , const char *note ) {
return dup ( string , gbstrlen ( string ) + 1 , note ); };
2014-11-11 01:45:11 +03:00
int32_t validate();
2013-08-03 00:12:24 +04:00
//void *gbmalloc2 ( int size , const char *note );
//void *gbcalloc2 ( int size , const char *note);
//void *gbrealloc2 ( void *oldPtr,int oldSize ,int newSize,
// const char *note);
//void gbfree2 ( void *ptr , int size , const char *note);
2014-11-11 01:45:11 +03:00
//char *dup2 ( const void *data , int32_t dataSize ,
2013-08-03 00:12:24 +04:00
// const char *note);
// this one does not include new/delete mem, only *alloc()/free() mem
2014-10-30 22:36:39 +03:00
int64_t getUsedMem () { return m_used; };
int64_t getAvailMem() ;
2013-08-03 00:12:24 +04:00
// the max mem ever alloced
2014-10-30 22:36:39 +03:00
int64_t getMaxAlloced() { return m_maxAlloced; };
int64_t getMaxAlloc () { return m_maxAlloc; };
2013-08-03 00:12:24 +04:00
const char *getMaxAllocBy() { return m_maxAllocBy; };
// the max mem we can use!
2014-10-30 22:36:39 +03:00
int64_t getMaxMem () ;
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
int32_t getNumAllocated() { return m_numAllocated; };
2013-08-03 00:12:24 +04:00
2014-10-30 22:36:39 +03:00
int64_t getNumTotalAllocated() { return m_numTotalAllocated; };
2013-08-03 00:12:24 +04:00
// # of currently allocated chunks
2014-11-11 01:45:11 +03:00
int32_t getNumChunks();
2013-08-03 00:12:24 +04:00
// for debugging
2014-11-11 01:45:11 +03:00
int32_t printBits ( void *src, int32_t b , int32_t nb );
2013-08-03 00:12:24 +04:00
// who underan/overran their buffers?
2014-11-11 01:45:11 +03:00
int printBreech ( int32_t i , char core ) ;
2013-08-03 00:12:24 +04:00
int printBreeches ( char core ) ;
// print mem usage stats
int printMem ( ) ;
void addMem ( void *mem , int32_t size , const char *note, char isnew);
2014-11-11 01:45:11 +03:00
bool rmMem ( void *mem , int32_t size , const char *note ) ;
bool lblMem ( void *mem , int32_t size , const char *note );
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
int32_t getMemSize ( void *mem );
int32_t getMemSlot ( void *mem );
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
void addnew ( void *ptr , int32_t size , const char *note ) ;
void delnew ( void *ptr , int32_t size , const char *note ) ;
2013-08-03 00:12:24 +04:00
bool printMemBreakdownTable(SafeBuf* sb,
char *lightblue,
char *darkblue);
// We can check the size of the stack from anywhere. However,
// setStackPointer() must be called from main, and ptr should
// be the address of the first variable declared in main.
void setStackPointer( char *ptr );
2014-11-11 01:45:11 +03:00
int32_t checkStackSize();
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
int32_t findPtr ( void *target ) ;
2013-08-03 00:12:24 +04:00
// alloc this much memory then immediately free it.
// this should assign this many pages to this process id so no other
// process can grab them -- only us.
// TODO: use sbrk()
2014-10-30 22:36:39 +03:00
// bool reserveMem ( int64_t bytesToReserve );
2013-08-03 00:12:24 +04:00
2014-10-30 22:36:39 +03:00
int64_t m_maxAlloced; // at any one time
int64_t m_maxAlloc; // the biggest single alloc ever done
2013-08-03 00:12:24 +04:00
const char *m_maxAllocBy; // the biggest single alloc ever done
//int64_t m_maxMem;
2013-08-03 00:12:24 +04:00
// shared mem used
2014-10-30 22:36:39 +03:00
int64_t m_sharedUsed;
2013-08-03 00:12:24 +04:00
// currently used mem (estimate)
2014-10-30 22:36:39 +03:00
int64_t m_used;
2013-08-03 00:12:24 +04:00
// count how many allocs/news failed
int32_t m_outOfMems;
2014-11-11 01:45:11 +03:00
int32_t m_numAllocated;
2014-10-30 22:36:39 +03:00
int64_t m_numTotalAllocated;
2014-11-11 01:45:11 +03:00
uint32_t m_memtablesize;
2013-08-03 00:12:24 +04:00
protected:
char *m_stackStart;
};
extern class Mem g_mem;
//#define mmalloc(size,note) malloc(size)
//#define mfree(ptr,size,note) free(ptr)
//#define mrealloc(oldPtr,oldSize,newSize,note) realloc(oldPtr,newSize)
inline void *mmalloc ( int size , const char *note ) {
return g_mem.gbmalloc(size,note); };
inline void *mcalloc ( int size , const char *note ) {
return g_mem.gbcalloc(size,note); };
inline void *mrealloc (void *oldPtr, int oldSize, int newSize,
const char *note) {
return g_mem.gbrealloc(oldPtr,oldSize,newSize,note);};
inline void mfree ( void *ptr , int size , const char *note) {
return g_mem.gbfree(ptr,size,note);};
2014-11-11 01:45:11 +03:00
inline char *mdup ( const void *data , int32_t dataSize , const char *note) {
2013-08-03 00:12:24 +04:00
return g_mem.dup(data,dataSize,note);};
inline char *mstrdup ( const char *string , const char *note ) {
return g_mem.strdup(string,note);};
2014-11-11 01:45:11 +03:00
inline void mnew ( void *ptr , int32_t size , const char *note ) {
2013-08-03 00:12:24 +04:00
return g_mem.addnew ( ptr , size , note );};
2014-11-11 01:45:11 +03:00
inline void mdelete ( void *ptr , int32_t size , const char *note ) {
2013-08-03 00:12:24 +04:00
return g_mem.delnew ( ptr , size , note ); };
2014-11-11 01:45:11 +03:00
inline bool relabel ( void *ptr , int32_t size , const char *note ) {
2013-08-03 00:12:24 +04:00
return g_mem.lblMem( ptr, size, note ); };
//#ifdef _LEAKCHECK_
// use a macro to make delete calls call g_mem.rmMem()
//#define delete(X) { delete X; g_mem.m_freed += sizeof(*X); g_mem.rmMem(X,sizeof(*X),"new"); }
//#elif
//#define delete(X) { delete X; g_mem.m_freed += sizeof(*X); }
//#endif
//#ifndef DMALLOC
2013-09-09 06:51:57 +04:00
void operator delete ( void *p ) throw();
void * operator new (size_t size) throw (std::bad_alloc);
2013-08-03 00:12:24 +04:00
// you MUST call mmalloc, mcalloc and mrealloc!!
#define malloc coreme
#define calloc coreme
#define realloc coreme
//#endif
inline void *coreme ( int x ) { char *xx = NULL; *xx = 0; return NULL; }
2014-11-11 01:45:11 +03:00
int32_t getAllocSize(void *p);
2013-08-03 00:12:24 +04:00
//void * operator new (size_t size) ;
2014-11-11 01:45:11 +03:00
inline int32_t getHighestLitBit ( uint16_t bits ) {
2013-08-03 00:12:24 +04:00
unsigned char b = *((unsigned char *)(&bits) + 1);
if ( ! b ) return getHighestLitBit ( (unsigned char) bits );
return 8 + getHighestLitBit ( (unsigned char) b );
}
2014-11-11 01:45:11 +03:00
inline int32_t getHighestLitBit ( unsigned char c ) {
2013-08-03 00:12:24 +04:00
static char a[256] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
return a[(unsigned char) c];
}
extern char g_a[];
2014-11-11 01:45:11 +03:00
inline int32_t getNumBitsOn8 ( unsigned char c ) {
2013-08-03 00:12:24 +04:00
return g_a[(unsigned char) c];
}
2014-11-11 01:45:11 +03:00
inline int32_t getNumBitsOn16 ( uint16_t bits ) {
2013-08-03 00:12:24 +04:00
return g_a [ *((unsigned char *)(&bits) + 0) ] +
g_a [ *((unsigned char *)(&bits) + 1) ] ;
}
2014-11-11 01:45:11 +03:00
inline int32_t getNumBitsOn32 ( uint32_t bits ) {
2013-08-03 00:12:24 +04:00
return g_a [ *((unsigned char *)(&bits) + 0) ] +
g_a [ *((unsigned char *)(&bits) + 1) ] +
g_a [ *((unsigned char *)(&bits) + 2) ] +
g_a [ *((unsigned char *)(&bits) + 3) ] ;
}
2014-11-11 01:45:11 +03:00
inline int32_t getNumBitsOn64 ( uint64_t bits ) {
2013-08-03 00:12:24 +04:00
return g_a [ *((unsigned char *)(&bits) + 0) ] +
g_a [ *((unsigned char *)(&bits) + 1) ] +
g_a [ *((unsigned char *)(&bits) + 2) ] +
g_a [ *((unsigned char *)(&bits) + 3) ] +
g_a [ *((unsigned char *)(&bits) + 4) ] +
g_a [ *((unsigned char *)(&bits) + 5) ] +
g_a [ *((unsigned char *)(&bits) + 6) ] +
g_a [ *((unsigned char *)(&bits) + 7) ] ;
}
inline int32_t getNumBitsOnX ( unsigned char *s , int32_t slen ) {
if ( slen == 1 ) return getNumBitsOn8 ( *s );
if ( slen == 2 ) return getNumBitsOn16 ( *(uint16_t *)s );
if ( slen == 4 ) return getNumBitsOn32 ( *(uint32_t *)s );
if ( slen == 3 )
return getNumBitsOn8 ( s[0] ) +
getNumBitsOn8 ( s[1] ) +
getNumBitsOn8 ( s[2] ) ;
int32_t total = 0;
for ( int32_t i = 0 ; i < slen ; i++ )
total += getNumBitsOn8 ( s[i] );
return total;
}
2013-08-03 00:12:24 +04:00
// assume only one bit is set for this (used by Address.cpp)
2014-11-11 01:45:11 +03:00
inline int32_t getBitPosLL ( uint8_t *bit ) {
// which int32_t is it in?
if ( *(int32_t *)bit ) {
2013-08-03 00:12:24 +04:00
if ( bit[0] ) return getHighestLitBit ( bit[0] );
if ( bit[1] ) return getHighestLitBit ( bit[1] ) + 8;
if ( bit[2] ) return getHighestLitBit ( bit[2] ) + 16;
if ( bit[3] ) return getHighestLitBit ( bit[3] ) + 24;
2013-08-03 00:12:24 +04:00
char *xx=NULL;*xx=0;
}
if ( bit[4] ) return getHighestLitBit ( bit[4] ) + 32;
if ( bit[5] ) return getHighestLitBit ( bit[5] ) + 40;
if ( bit[6] ) return getHighestLitBit ( bit[6] ) + 48;
if ( bit[7] ) return getHighestLitBit ( bit[7] ) + 56;
char *xx=NULL;*xx=0;
return -1;
}
#endif