void check_memory_state(void) { t_sysfree sysfree = free; /* (t_sysfree)dlsym(RTLD_NEXT, "free"); */ if (memory_check == 0) { sysfree(memory_head()); return ; } struct memhead *head; int i; head = memory_head(); fprintf(stderr, "Call to malloc: %lu\n", head->alloc_count); fprintf(stderr, "Sum of all byte requested: %lu\n", head->total_count); fprintf(stderr, "Allocated chunks at the end of the program: %lu\n", head->alloc); fprintf(stderr, "Allocated bytes at the end of the program: %lu\n", head->total); i = check_tree(head->first); fprintf(stderr, "Altered chunks: %d\n", i); sysfree(memory_head()); if (i) { kill(getpid(), SIGSEGV); sleep(2); exit(EXIT_FAILURE); } }
void Mem::gbfree ( void *ptr , int size , const char *note ) { logTrace( g_conf.m_logTraceMem, "ptr=%p size=%d note='%s'", ptr, size, note ); // don't let electric fence zap us //if ( size == 0 && ptr==(void *)0x7fffffff) return; if ( size == 0 ) return; // huh? if ( ! ptr ) return; // . get how much it was from the mem table // . this is used for alloc/free wrappers for zlib because it does // not give us a size to free when it calls our mfree(), so we use -1 int32_t slot = g_mem.getMemSlot ( ptr ); if ( slot < 0 ) { log(LOG_LOGIC,"mem: could not find slot (note=%s)",note); //Do NOT abort here... Let it run, otherwise it dies during merges. abort(); //log(LOG_LOGIC,"mem: FIXME!!!"); // return for now so procog does not core all the time! return; //char *xx = NULL; *xx = 0; } bool isnew = s_isnew[slot]; // if this returns false it was an unbalanced free if ( ! rmMem ( ptr , size , note ) ) return; g_inMemFunction = true; if ( isnew ) sysfree ( (char *)ptr ); else sysfree ( (char *)ptr - UNDERPAD ); g_inMemFunction = false; }
static void pipe_close(struct idesc *idesc) { struct pipe *pipe; struct idesc_pipe *cur, *other; int ret; assert(idesc); assert(idesc->idesc_ops == &idesc_pipe_ops); cur = ((struct idesc_pipe *) idesc); pipe = idesc_to_pipe(idesc); mutex_lock(&pipe->mutex); if (cur == &pipe->read_desc) { other = &pipe->write_desc; } else { assert(cur == &pipe->write_desc); other = &pipe->read_desc; } ret = idesc_pipe_close(cur, other); mutex_unlock(&pipe->mutex); if (ret) { sysfree(pipe->buff->storage); sysfree(pipe->buff); sysfree(pipe); } }
void Mem::gbfree ( void *ptr , const char *note, size_t size , bool checksize ) { if(!s_lock.working) return; logTrace( g_conf.m_logTraceMem, "ptr=%p size=%zu note='%s'", ptr, size, note ); if ((checksize && size == 0) || !ptr) { return; } // . get how much it was from the mem table // . this is used for alloc/free wrappers for zlib because it does // not give us a size to free when it calls our mfree(), so we use -1 int32_t slot = g_mem.getMemSlot ( ptr ); if ( slot < 0 ) { log(LOG_LOGIC,"mem: could not find slot (note=%s)",note); // do NOT abort here... Let it run, otherwise it dies during merges. abort(); // return for now so procog does not core all the time! return; } bool isnew = s_isnew[slot]; // if this returns false it was an unbalanced free if (!rmMem(ptr, size, note, checksize)) { return; } if ( isnew ) sysfree ( (char *)ptr ); else sysfree ( (char *)ptr - UNDERPAD ); }
static struct pipe *pipe_alloc(void) { struct pipe *pipe; struct ring_buff *pipe_buff; void *storage; storage = sysmalloc(DEFAULT_PIPE_BUFFER_SIZE); if (!storage) { return NULL; } pipe = sysmalloc(sizeof(struct pipe)); if (!pipe) { sysfree(storage); return NULL; } pipe_buff = sysmalloc(sizeof(struct ring_buff)); if (!pipe_buff) { sysfree(storage); sysfree(pipe); return NULL; } pipe->buff = pipe_buff; pipe->buf_size = DEFAULT_PIPE_BUFFER_SIZE - 1; ring_buff_init(pipe_buff, 1, DEFAULT_PIPE_BUFFER_SIZE, storage); mutex_init(&pipe->mutex); return pipe; }
void InsLibFreeHost(InsLibHostDesc *hostd) { if (hostd) { InsLibFreeDriver(hostd->Drivers); sysfree((char *) hostd, sizeof(InsLibHostDesc)); } }
void InsLibFreePci(InsLibPciModuleAddress *pcima) { if (pcima) { InsLibFreePciSpace(pcima->PciAddressSpace); sysfree((char *) pcima, sizeof(InsLibPciModuleAddress)); } }
void InsLibFreeVme(InsLibVmeModuleAddress *vmema) { if (vmema) { InsLibFreeVmeSpace(vmema->VmeAddressSpace); sysfree((char *) vmema, sizeof(InsLibVmeModuleAddress)); } }
void InsLibFreeCar(InsLibCarModuleAddress *carma) { if (carma) { InsLibFreeCarSpace(carma->CarAddressSpace); sysfree((char *) carma, sizeof(InsLibCarModuleAddress)); } }
void InsLibFreePciSpace(InsLibPciAddressSpace *pcias) { if (pcias) { InsLibFreePciSpace(pcias->Next); sysfree((char *) pcias, sizeof(InsLibPciAddressSpace)); } }
void InsLibFreeCarSpace(InsLibCarAddressSpace *caras) { if (caras) { InsLibFreeCarSpace(caras->Next); sysfree((char *) caras, sizeof(InsLibCarAddressSpace)); } }
void InsLibFreeVmeSpace(InsLibVmeAddressSpace *vmeas) { if (vmeas) { InsLibFreeVmeSpace(vmeas->Next); sysfree((char *) vmeas, sizeof(InsLibVmeAddressSpace)); } }
static int flash_emu_erase_block (struct flash_dev *dev, uint32_t block_base) { block_dev_t *bdev; int len; char * data; int rc; bdev = dev->privdata; if(NULL == bdev) { return -ENODEV; } len = bdev->driver->ioctl(bdev, IOCTL_GETBLKSIZE, NULL, 0); if(NULL == (data = sysmalloc(len))) { return -ENOMEM; } memset((void *) data, 0xFF, (size_t) len); rc = block_dev_write_buffered(bdev, (const char *) data, (size_t) len, block_base); sysfree(data); if(len == rc) { return 0; } return rc; }
/** * @brief User entry point in driver/simulator unistall routine. * * @param proceed -- if standard code execution should be proceed * @param sptr -- statics table pointer * * It's up to user to set kernel-level errno (by means of @e pseterr call). * @e proceed parameter denotes if further standard actions should be proceed * after function returns. @b FALSE - means that user-desired operation done * all that user wants and there is no further necessaty to perfom any standard * operations that follow function call. @b TRUE - means that code that follows * function call will be executed. * * @return return value is the same as in entry point function.\n * OK - if succeed.\n * SYSERR - in case of failure. */ int CvorbUserUnInst(int *proceed, CVORBStatics_t *sptr) { //CVORBUserStatics_t *usp = sptr->usrst; /* user statistics table */ /* Uncomment the following code to unregister ISR */ #if 0 kkprintf("Cvorb: Interrupt routine managment" " cleanup ( vector number [%d] ) - ", sptr->info->iVector); #ifdef __Lynx__ #ifdef __powerpc__ /* in this case we are using CES BSP */ vme_intclr(sptr->info->iVector, 0); #else iointclr(sptr->info->iVector); #endif #else /* __linux__ */ vme_free_irq(sptr->info->iVector); #endif /* __Lynx__ */ kkprintf("OK\n"); #endif sysfree((char*)sptr->usrst->md, sizeof(_m)); if (proceed) *proceed = TRUE; /* continue standard code execution */ return OK; /* succeed */ }
int Mem::printMem ( ) { // has anyone breeched their buffer? printBreeches_unlocked(); // print table entries sorted by most mem first int32_t *p = (int32_t *)sysmalloc ( m_memtablesize * 4 ); if ( ! p ) return 0; // stock up "p" and compute total bytes allocated int64_t total = 0; int32_t np = 0; for ( int32_t i = 0 ; i < (int32_t)m_memtablesize ; i++ ) { // skip empty buckets if ( ! s_mptrs[i] ) continue; total += s_sizes[i]; p[np++] = i; } // print out table sorted by sizes for ( int32_t i = 0 ; i < np ; i++ ) { int32_t a = p[i]; log(LOG_INFO,"mem: %05" PRId32") %zu 0x%" PTRFMT" %s", i,s_sizes[a] , (PTRTYPE)s_mptrs[a] , &s_labels[a*16] ); } sysfree ( p ); log(LOG_INFO,"mem: # current objects allocated now = %" PRId32, np ); log(LOG_INFO,"mem: totalMem allocated now = %" PRId64, total ); //log("mem: max allocated at one time = %" PRId32, (int32_t)(m_maxAllocated)); log(LOG_INFO,"mem: Memory allocated now: %" PRId64".\n", m_used ); log(LOG_INFO,"mem: Num allocs %" PRId32".\n", m_numAllocated ); return 1; }
void InsLibFreeDriver(InsLibDrvrDesc *drvrd) { if (drvrd) { InsLibFreeDriver(drvrd->Next); InsLibFreeModule(drvrd->Modules); sysfree((char *) drvrd, sizeof(InsLibDrvrDesc)); } }
void SkelUserModuleRelease(SkelDrvrModuleContext *mcon) { /* quiesce the module before it gets uninstalled */ __mtt_quiesce(mcon); /* free userdata */ sysfree(mcon->UserData, sizeof(struct udata)); }
void InsLibFreeModule(InsLibModlDesc *modld) { if (modld) { InsLibFreeModule(modld->Next); if (modld->BusType == InsLibBusTypeCARRIER) InsLibFreeCar(modld->ModuleAddress); else if (modld->BusType == InsLibBusTypeVME) InsLibFreeVme(modld->ModuleAddress); else if ( (modld->BusType == InsLibBusTypePMC) || (modld->BusType == InsLibBusTypePCI) ) InsLibFreePci(modld->ModuleAddress); if (modld->Extra) sysfree((char *) modld->Extra, strlen(modld->Extra)); if (modld->Isr) sysfree((char *) modld->Isr, sizeof(InsLibIntrDesc)); } }
static SkelUserReturn mtt_gs_program(struct udata *udata, MttDrvrInstruction *u_prog, MttDrvrInstruction *io_prog, unsigned int elems, int set) { void *bounce; ssize_t size = elems * sizeof(MttDrvrInstruction); bounce = (void *)sysbrk(size); if (bounce == NULL) { SK_ERROR("%s: -ENOMEM", __FUNCTION__); pseterr(ENOMEM); goto out_err; } if (set) { if (cdcm_copy_from_user(bounce, u_prog, size)) { pseterr(EFAULT); goto out_err; } cdcm_mutex_lock(&udata->lock); __mtt_set_program(udata, io_prog, bounce, elems); cdcm_mutex_unlock(&udata->lock); } else { cdcm_mutex_lock(&udata->lock); __mtt_get_program(udata, bounce, io_prog, elems); cdcm_mutex_unlock(&udata->lock); if (cdcm_copy_to_user(u_prog, bounce, size)) { pseterr(EFAULT); goto out_err; } } sysfree(bounce, size); return SkelUserReturnOK; out_err: if (bounce) sysfree(bounce, size); return SkelUserReturnFAILED; }
static SkelUserReturn __mtt_io(SkelDrvrModuleContext *mcon, void *u_addr, void *ioaddr, ssize_t size, int write) { struct udata *udata = mcon->UserData; void *bounce; bounce = (void *)sysbrk(size); if (bounce == NULL) { report_module(mcon, SkelDrvrDebugFlagASSERTION, "%s: -ENOMEM", __FUNCTION__); pseterr(ENOMEM); goto out_err; } if (write) { if (cdcm_copy_from_user(bounce, u_addr, size)) { pseterr(EFAULT); goto out_err; } cdcm_mutex_lock(&udata->lock); mtt_iowritew_r(ioaddr, bounce, size); cdcm_mutex_unlock(&udata->lock); } else { cdcm_mutex_lock(&udata->lock); mtt_ioreadw_r(bounce, ioaddr, size); cdcm_mutex_unlock(&udata->lock); if (cdcm_copy_to_user(u_addr, bounce, size)) { pseterr(EFAULT); goto out_err; } } sysfree(bounce, size); return SkelUserReturnOK; out_err: if (bounce) sysfree(bounce, size); return SkelUserReturnFAILED; }
void skb_data_free(struct sk_buff_data *skb_data) { ipl_t sp; assert(skb_data != NULL); sp = ipl_save(); { if (--skb_data->links == 0) { if (pool_belong(&skb_data_pool, skb_data)) { pool_free(&skb_data_pool, skb_data); } else { sysfree(skb_data); } } } ipl_restore(sp); }
SkelUserReturn SkelUserModuleInit(SkelDrvrModuleContext *mcon) { struct udata *udata; udata = (void *)sysbrk(sizeof(struct udata)); if (udata == NULL) { report_module(mcon, SkelDrvrDebugFlagASSERTION, "Not enough memory for the module's data"); pseterr(ENOMEM); return SkelUserReturnFAILED; } bzero((void *)udata, sizeof(struct udata)); mcon->UserData = udata; /* initialise the iomap address */ udata->iomap = get_vmemap_addr(mcon, 0x39, 32); if (!udata->iomap) { SK_WARN("Could not find VME address space (0x39, 32)"); goto out_free; } /* initialise the jtag address */ udata->jtag = get_vmemap_addr(mcon, 0x29, 16); if (!udata->jtag) { SK_WARN("Could not find VME address space (0x29, 16)"); goto out_free; } /* initialise locking fields */ cdcm_spin_lock_init(&udata->iolock); cdcm_mutex_init(&udata->lock); /* initialise the tasks */ mtt_tasks_init(udata); /* module software reset */ SkelUserHardwareReset(mcon); return SkelUserReturnOK; out_free: sysfree((void*)udata, sizeof(struct udata)); return SkelUserReturnFAILED; }
static int ext3fs_umount(void *dir) { struct fs_driver *drv; struct ext2_fs_info *fsi; ext3_journal_specific_t *data; int res; fsi = ((struct node *)dir)->nas->fs->fsi; data = fsi->journal->j_fs_specific.data; if(NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return -1; } res = drv->fsop->umount(dir); journal_delete(fsi->journal); sysfree(data->ext3_journal_inode); journal_free_block(fsi->journal, data->j_sb_buffer); objfree(&ext3_journal_cache, data); return res; }
void *Mem::gbrealloc ( void *ptr , size_t oldSize , size_t newSize , const char *note ) { logTrace( g_conf.m_logTraceMem, "ptr=%p oldSize=%zu newSize=%zu note='%s'", ptr, oldSize, newSize, note ); // return dummy values since realloc() returns NULL if failed if ( oldSize == 0 && newSize == 0 ) return (void *)0x7fffffff; // do nothing if size is same if ( oldSize == newSize ) return ptr; // if newSize is 0... if ( newSize == 0 ) { gbfree(ptr, note, oldSize, true); return (void *)0x7fffffff; } retry: // hack so hostid #0 can use more mem size_t max = g_conf.m_maxMem; //if ( g_hostdb.m_hostId == 0 ) max += 2000000000; // don't go over max if ( g_mem.getUsedMem() + newSize - oldSize >= max ) { // try to free temp mem. returns true if it freed some. if ( freeCacheMem() ) goto retry; g_errno = ENOMEM; log( LOG_WARN, "mem: realloc(%zu,%zu): Out of memory.",oldSize,newSize); return NULL; } // if oldSize is 0, use our malloc() instead if ( oldSize == 0 ) { return gbmalloc ( newSize , note ); } // assume it will be successful. we can't call rmMem() after // calling sysrealloc() because it will mess up our MAGICCHAR buf rmMem(ptr, oldSize, note, true); // . do the actual realloc // . CAUTION: don't pass in 0x7fffffff in as "ptr" // . this was causing problems char *mem = (char *)sysrealloc ( (char *)ptr - UNDERPAD , newSize + UNDERPAD + OVERPAD ); // remove old guy on sucess if ( mem ) { addMem ( (char *)mem + UNDERPAD , newSize , note , 0 ); char *returnMem = mem + UNDERPAD; // set magic char bytes for mem for ( int32_t i = 0 ; i < UNDERPAD ; i++ ) returnMem[0-i-1] = MAGICCHAR; for ( int32_t i = 0 ; i < OVERPAD ; i++ ) returnMem[0+newSize+i] = MAGICCHAR; return returnMem; } // ok, just try using malloc then! mem = (char *)mmalloc ( newSize , note ); // bail on error if ( ! mem ) { g_mem.m_outOfMems++; // restore the original buf we tried to grow addMem ( ptr , oldSize , note , 0 ); errno = g_errno = ENOMEM; return NULL; } // log a note log(LOG_INFO,"mem: had to use malloc+memcpy instead of realloc."); // copy over to it memcpy ( mem, ptr, oldSize ); // we already called rmMem() so don't double call sysfree ( (char *)ptr - UNDERPAD ); return mem; }
void *Mem::gbmalloc ( size_t size , const char *note ) { logTrace( g_conf.m_logTraceMem, "size=%zu note='%s'", size, note ); // don't let electric fence zap us if ( size == 0 ) return (void *)0x7fffffff; if ( allocationShouldFailRandomly() ) { g_errno = ENOMEM; log( LOG_WARN, "mem: malloc-fake(%zu,%s): %s",size,note, mstrerror(g_errno)); return NULL; } retry: size_t max = g_conf.m_maxMem; // don't go over max if ( g_mem.getUsedMem() + size + UNDERPAD + OVERPAD >= max ) { // try to free temp mem. returns true if it freed some. if ( freeCacheMem() ) goto retry; g_errno = ENOMEM; log( LOG_WARN, "mem: malloc(%zu): Out of memory", size ); return NULL; } void *mem; mem = (void *)sysmalloc ( size + UNDERPAD + OVERPAD ); int32_t memLoop = 0; mallocmemloop: if ( ! mem && size > 0 ) { g_mem.m_outOfMems++; // try to free temp mem. returns true if it freed some. if ( freeCacheMem() ) goto retry; g_errno = errno; static int64_t s_lastTime; static int32_t s_missed = 0; int64_t now = gettimeofdayInMillisecondsLocal(); int64_t avail = (int64_t)g_conf.m_maxMem - (int64_t)m_used; if ( now - s_lastTime >= 1000LL ) { log(LOG_WARN, "mem: system malloc(%zu,%s) availShouldBe=%" PRId64": " "%s (%s) (ooms suppressed since last log msg = %" PRId32")", size+UNDERPAD+OVERPAD, note, avail, mstrerror(g_errno), note, s_missed); s_lastTime = now; s_missed = 0; } else { s_missed++; } return NULL; } if ( (PTRTYPE)mem < 0x00010000 ) { void *remem = sysmalloc(size); log( LOG_WARN, "mem: Caught low memory allocation " "at %08" PTRFMT", " "reallocated to %08" PTRFMT"", (PTRTYPE)mem, (PTRTYPE)remem ); sysfree(mem); mem = remem; memLoop++; if ( memLoop > 100 ) { log( LOG_WARN, "mem: Attempted to reallocate low " "memory allocation 100 times, " "aborting and returning NOMEM." ); g_errno = ENOMEM; return NULL; } goto mallocmemloop; } logTrace( g_conf.m_logTraceMem, "mem=%p size=%zu note='%s'", mem, size, note ); addMem ( (char *)mem + UNDERPAD , size , note , 0 ); return (char *)mem + UNDERPAD; }
// this is called after a memory block has been allocated and needs to be registered void Mem::addMem ( void *mem , size_t size , const char *note , char isnew ) { if(!s_lock.working) return; ScopedLock sl(s_lock); logTrace( g_conf.m_logTraceMem, "mem=%p size=%zu note='%s' is_new=%d", mem, size, note, isnew ); //validate(); // 4G/x = 600*1024 -> x = 4000000000.0/(600*1024) = 6510 // crap, g_hostdb.init() is called inmain.cpp before // g_conf.init() which is needed to set g_conf.m_maxMem... if ( ! s_initialized ) { //m_memtablesize = m_maxMem / 6510; // support 1.2M ptrs for now. good for about 8GB // raise from 3000 to 8194 to fix host #1 m_memtablesize = 8194*1024;//m_maxMem / 6510; //if ( m_maxMem < 8000000000 ) gbshutdownLogicError(); } if ( (int32_t)m_numAllocated + 100 >= (int32_t)m_memtablesize ) { static bool s_printed = false; if ( ! s_printed ) { log(LOG_WARN, "mem: using too many slots"); printMem(); s_printed = true; } } logDebug( g_conf.m_logDebugMem, "mem: add %08" PTRFMT" %zu bytes (%" PRId64") (%s)", (PTRTYPE)mem, size, m_used, note ); // check for breech after every call to alloc or free in order to // more easily isolate breeching code.. this slows things down a lot // though. if ( g_conf.m_logDebugMem ) printBreeches_unlocked(); // copy the magic character, iff not a new() call if ( size == 0 ) { sl.unlock(); gbshutdownLogicError(); } // sanity check -- for machines with > 4GB ram? if ( (PTRTYPE)mem + (PTRTYPE)size < (PTRTYPE)mem ) { log(LOG_LOGIC,"mem: Kernel returned mem at " "%08" PTRFMT" of size %" PRId32" " "which would wrap. Bad kernel.", (PTRTYPE)mem,(int32_t)size); sl.unlock(); gbshutdownLogicError(); } // umsg00 // bool useElectricFence = false; // if ( ! isnew && ! useElectricFence ) { if ( ! isnew ) { for ( int32_t i = 0 ; i < UNDERPAD ; i++ ) ((char *)mem)[0-i-1] = MAGICCHAR; for ( int32_t i = 0 ; i < OVERPAD ; i++ ) ((char *)mem)[0+size+i] = MAGICCHAR; } // if no label! if ( ! note[0] ) log(LOG_LOGIC,"mem: addmem: NO note."); // clear mem ptrs if this is our first call if ( ! s_initialized ) { s_mptrs = (void **)sysmalloc ( m_memtablesize*sizeof(void *)); s_sizes = (size_t *)sysmalloc(m_memtablesize * sizeof(size_t)); s_labels = (char *)sysmalloc ( m_memtablesize*16 ); s_isnew = (char *)sysmalloc ( m_memtablesize ); if ( ! s_mptrs || ! s_sizes || ! s_labels || ! s_isnew ) { if ( s_mptrs ) sysfree ( s_mptrs ); if ( s_sizes ) sysfree ( s_sizes ); if ( s_labels ) sysfree ( s_labels ); if ( s_isnew ) sysfree ( s_isnew ); log(LOG_WARN, "mem: addMem: Init failed. Disabling checks."); g_conf.m_detectMemLeaks = false; return; } s_initialized = true; memset ( s_mptrs , 0 , sizeof(char *) * m_memtablesize ); } // try to add ptr/size/note to leak-detecting table if ( (int32_t)s_n > (int32_t)m_memtablesize ) { log( LOG_WARN, "mem: addMem: No room in table for %s size=%zu.", note,size); return; } // hash into table uint32_t u = (PTRTYPE)mem * (PTRTYPE)0x4bf60ade; uint32_t h = u % (uint32_t)m_memtablesize; // chain to an empty bucket int32_t count = (int32_t)m_memtablesize; while ( s_mptrs[h] ) { // if an occupied bucket as our same ptr then chances are // we freed without calling rmMem() and a new addMem() got it if ( s_mptrs[h] == mem ) { // if we are being called from addnew(), the // overloaded "operator new" function above should // have stored a temp ptr in here... allow that, it // is used in case an engineer forgets to call // mnew() after calling new() so gigablast would never // realize that the memory was allocated. if ( s_sizes[h] == size && s_labels[h*16+0] == 'T' && s_labels[h*16+1] == 'M' && s_labels[h*16+2] == 'P' && s_labels[h*16+3] == 'M' && s_labels[h*16+4] == 'E' && s_labels[h*16+5] == 'M' ) { goto skipMe; } log( LOG_ERROR, "mem: addMem: Mem already added. rmMem not called? label=%c%c%c%c%c%c", s_labels[h*16+0], s_labels[h*16+1], s_labels[h*16+2], s_labels[h*16+3], s_labels[h*16+4], s_labels[h*16+5] ); sl.unlock(); gbshutdownAbort(true); } h++; if ( h == m_memtablesize ) h = 0; if ( --count == 0 ) { log( LOG_ERROR, "mem: addMem: Mem table is full."); printMem(); sl.unlock(); gbshutdownResourceError(); } } // add to debug table s_mptrs [ h ] = mem; s_sizes [ h ] = size; s_isnew [ h ] = isnew; //log("adding %" PRId32" size=%" PRId32" to [%" PRId32"] #%" PRId32" (%s)", //(int32_t)mem,size,h,s_n,note); s_n++; // debug if ( (size > MINMEM && g_conf.m_logDebugMemUsage) || size>=100000000 ) log(LOG_INFO,"mem: addMem(%zu): %s. ptr=0x%" PTRFMT" " "used=%" PRId64, size,note,(PTRTYPE)mem,m_used); // now update used mem // we do this here now since we always call addMem() now m_used += size; m_numAllocated++; m_numTotalAllocated++; if ( size > m_maxAlloc ) { m_maxAlloc = size; m_maxAllocBy = note; } if ( m_used > m_maxAllocated ) m_maxAllocated = m_used; skipMe: int32_t len = strlen(note); if ( len > 15 ) len = 15; char *here = &s_labels [ h * 16 ]; memcpy ( here , note , len ); // make sure NULL terminated here[len] = '\0'; //validate(); }
void *Mem::gbmalloc ( int size , const char *note ) { logTrace( g_conf.m_logTraceMem, "size=%d note='%s'", size, note ); // don't let electric fence zap us if ( size == 0 ) return (void *)0x7fffffff; // random oom testing //static int32_t s_mcount = 0; //s_mcount++; if ( g_conf.m_testMem && (rand() % 100) < 2 ) { //if ( s_mcount > 1055 && (rand() % 1000) < 2 ) { g_errno = ENOMEM; log( LOG_WARN, "mem: malloc-fake(%i,%s): %s",size,note, mstrerror(g_errno)); return NULL; } retry: int64_t max = g_conf.m_maxMem; // don't go over max if ( m_used + size + UNDERPAD + OVERPAD >= max ) { // try to free temp mem. returns true if it freed some. if ( freeCacheMem() ) goto retry; g_errno = ENOMEM; log( LOG_WARN, "mem: malloc(%i): Out of memory", size ); return NULL; } if ( size < 0 ) { g_errno = EBADENGINEER; log( LOG_ERROR, "mem: malloc(%i): Bad value.", size ); char *xx = NULL; *xx = 0; return NULL; } void *mem; g_inMemFunction = true; mem = (void *)sysmalloc ( size + UNDERPAD + OVERPAD ); g_inMemFunction = false; int32_t memLoop = 0; mallocmemloop: if ( ! mem && size > 0 ) { g_mem.m_outOfMems++; // try to free temp mem. returns true if it freed some. if ( freeCacheMem() ) goto retry; g_errno = errno; static int64_t s_lastTime; static int32_t s_missed = 0; int64_t now = gettimeofdayInMillisecondsLocal(); int64_t avail = (int64_t)g_conf.m_maxMem - (int64_t)m_used; if ( now - s_lastTime >= 1000LL ) { log(LOG_WARN, "mem: system malloc(%i,%s) availShouldBe=%" PRId64": " "%s (%s) (ooms suppressed since last log msg = %" PRId32")", size+UNDERPAD+OVERPAD, note, avail, mstrerror(g_errno), note, s_missed); s_lastTime = now; s_missed = 0; } else { s_missed++; } // to debug oom issues: //char *xx=NULL;*xx=0; // send an email alert if this happens! it is a sign of "memory fragmentation" //static bool s_sentEmail = false; // stop sending these now... seems to be problematic. says // 160MB is avail and can't alloc 20MB... static bool s_sentEmail = true; // assume only 90% is really available because of // inefficient mallocing avail = (int64_t)((float)avail * 0.80); // but if it is within about 15MB of what is theoretically // available, don't send an email, because there is always some // minor fragmentation if ( ! s_sentEmail && avail > size ) { s_sentEmail = true; char msgbuf[1024]; Host *h = g_hostdb.m_myHost; snprintf(msgbuf, 1024, "Possible memory fragmentation " "on host #%" PRId32" %s", h->m_hostId,h->m_note); log(LOG_WARN, "query: %s",msgbuf); g_pingServer.sendEmail(NULL, msgbuf,true,true); } return NULL; } if ( (PTRTYPE)mem < 0x00010000 ) { void *remem = sysmalloc(size); log ( LOG_WARN, "mem: Caught low memory allocation " "at %08" PTRFMT", " "reallocated to %08" PTRFMT"", (PTRTYPE)mem, (PTRTYPE)remem ); sysfree(mem); mem = remem; memLoop++; if ( memLoop > 100 ) { log ( LOG_WARN, "mem: Attempted to reallocate low " "memory allocation 100 times, " "aborting and returning NOMEM." ); g_errno = ENOMEM; return NULL; } goto mallocmemloop; } logTrace( g_conf.m_logTraceMem, "mem=%p size=%d note='%s'", mem, size, note ); addMem ( (char *)mem + UNDERPAD , size , note , 0 ); return (char *)mem + UNDERPAD; }
// . global override of new and delete operators // . seems like constructor and destructor are still called // . just use to check if enough memory // . before this just called mmalloc which sometimes returned NULL which // would cause us to throw an unhandled signal. So for now I don't // call mmalloc since it is limited in the mem it can use and would often // return NULL and set g_errno to ENOMEM void * operator new (size_t size) throw (std::bad_alloc) { logTrace( g_conf.m_logTraceMem, "size=%zu", size ); // don't let electric fence zap us if ( size == 0 ) return (void *)0x7fffffff; // . fail randomly // . good for testing if we can handle out of memory gracefully //static int32_t s_mcount = 0; //s_mcount++; //if ( s_mcount > 57 && (rand() % 1000) < 2 ) { if ( g_conf.m_testMem && (rand() % 100) < 2 ) { g_errno = ENOMEM; log(LOG_ERROR, "mem: new-fake(%" PRIu32"): %s",(uint32_t)size, mstrerror(g_errno)); throw std::bad_alloc(); // return NULL; } } // hack so hostid #0 can use more mem int64_t max = g_conf.m_maxMem; //if ( g_hostdb.m_hostId == 0 ) max += 2000000000; // don't go over max if ( g_mem.m_used + (int32_t)size >= max && g_conf.m_maxMem > 1000000 ) { log("mem: new(%" PRIu32"): Out of memory.", (uint32_t)size ); throw std::bad_alloc(); //throw 1; } g_inMemFunction = true; void *mem = sysmalloc ( size ); g_inMemFunction = false; int32_t memLoop = 0; newmemloop: if ( ! mem && size > 0 ) { g_mem.m_outOfMems++; g_errno = errno; log( LOG_WARN, "mem: new(%" PRId32"): %s",(int32_t)size,mstrerror(g_errno)); throw std::bad_alloc(); //return NULL; } if ( (PTRTYPE)mem < 0x00010000 ) { void *remem = sysmalloc(size); log ( LOG_WARN, "mem: Caught low memory allocation " "at %08" PTRFMT", " "reallocated to %08" PTRFMT, (PTRTYPE)mem, (PTRTYPE)remem ); sysfree(mem); mem = remem; if ( memLoop > 100 ) { log ( LOG_WARN, "mem: Attempted to reallocate low " "memory allocation 100 times, " "aborting and returning ENOMEM." ); g_errno = ENOMEM; throw std::bad_alloc(); } goto newmemloop; } g_mem.addMem ( mem , size , "TMPMEM" , 1 ); return mem; }
/** * @brief User entry point in driver/simulator installation routine. * * @param proceed -- if standard code execution should be proceed * @param info -- driver info table * @param sptr -- statics table * * It's up to user to set kernel-level errno (by means of @e pseterr call). * @e proceed parameter denotes if further standard actions should be proceed * after function returns. @b FALSE - means that user-desired operation done * all that user wants and there is no further necessaty to perfom any standard * operations that follow function call. @b TRUE - means that code that follows * function call will be executed. * * @return return value is the same as in entry point function.\n * pointer to a statics data structure - if succeed.\n * SYSERR - in case of failure. */ char* CvorbUserInst(int *proceed, register DevInfo_t *info, register CVORBStatics_t *sptr) { CVORBUserStatics_t *usp = sptr->usrst; /* user statistics table */ int iVec = 0; /* interrupt vector */ int m, c; iVec = info->iVector; /* set up interrupt vector */ /* map submodule address pointers */ usp->md = (struct cvorb_module *)sysbrk(sizeof(_m)); usp->md[0].md = (mod *)sptr->card->block00; usp->md[1].md = (mod *)((long)sptr->card->block00 + 0x200); if (!firmware_ok(usp, info->mlun)) { sysfree((char *)usp->md, sizeof(_m)); return (char *)SYSERR; } for (m = 0; m < SMAM; m++) { /* reset subModules */ _wr(m, SOFT_PULSE, SPR_FGR); /* initialize iolock mutex */ cdcm_mutex_init(&usp->md[m].iol); /* set submodule channels addresses */ for (c = 0; c < CHAM; c++) usp->md[m].cd[c] = (chd *) ((long)usp->md[m].md + _ch_offset[c]); } /* init on-board DAC */ ad9516o_init(usp); /* disable on-board clock generator */ _wr(0, CLK_GEN_CNTL, AD9516_OFF); /* set normal mode operation, enable all channels and set recurrent cycles to 1 (i.e. play function once) */ enable_modules(usp); /* Uncomment the following code to register ISR */ #if 0 if (iVec > 0) { int cc = 0; /* completion code */ kkprintf("ISR ( vector number [%d] ) installation - ", iVec); #ifdef __Lynx__ #ifdef __powerpc__ /* in this case we are using CES BSP */ cc = vme_intset(iVec, (int (*)())CvorbISR, (char*)sptr, 0); #else /* use standard system call otherwise */ cc = iointset(iVec, (int (*)())CvorbISR, (char*)sptr); #endif #else /* __linux__ */ cc = vme_request_irq(iVec, (int (*)(void *))CvorbISR, (char *)sptr, "CvorbD"); #endif /* __Lynx__ */ if (cc < 0) { kkprintf("Failed.\n"); pseterr(EFAULT); /* TODO. what error to set? */ return (char*)SYSERR; /* -1 */ } kkprintf("interrupt vector managed.\n"); } #endif if (proceed) *proceed = TRUE; /* continue standard code execution */ return (char *)sptr; /* succeed */ }
void jffs2_free_inode_cache(struct jffs2_inode_cache *x) { D1(printk(KERN_DEBUG "Freeing inocache at %p\n", x)); sysfree(x); }