예제 #1
0
파일: malloc.cpp 프로젝트: thecyril/Wolf3D
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);
    }
}
예제 #2
0
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;
}
예제 #3
0
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);
	}
}
예제 #4
0
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 );
}
예제 #5
0
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;
}
예제 #6
0
void InsLibFreeHost(InsLibHostDesc *hostd)
{
	if (hostd) {
		InsLibFreeDriver(hostd->Drivers);
		sysfree((char *) hostd, sizeof(InsLibHostDesc));
	}
}
예제 #7
0
void InsLibFreePci(InsLibPciModuleAddress *pcima)
{
	if (pcima) {
		InsLibFreePciSpace(pcima->PciAddressSpace);
		sysfree((char *) pcima, sizeof(InsLibPciModuleAddress));
	}
}
예제 #8
0
void InsLibFreeVme(InsLibVmeModuleAddress *vmema)
{
	if (vmema) {
		InsLibFreeVmeSpace(vmema->VmeAddressSpace);
		sysfree((char *) vmema, sizeof(InsLibVmeModuleAddress));
	}
}
예제 #9
0
void InsLibFreeCar(InsLibCarModuleAddress *carma)
{
	if (carma) {
		InsLibFreeCarSpace(carma->CarAddressSpace);
		sysfree((char *) carma, sizeof(InsLibCarModuleAddress));
	}
}
예제 #10
0
void InsLibFreePciSpace(InsLibPciAddressSpace *pcias)
{
	if (pcias) {
		InsLibFreePciSpace(pcias->Next);
		sysfree((char *) pcias, sizeof(InsLibPciAddressSpace));
	}
}
예제 #11
0
void InsLibFreeCarSpace(InsLibCarAddressSpace *caras)
{
	if (caras) {
		InsLibFreeCarSpace(caras->Next);
		sysfree((char *) caras, sizeof(InsLibCarAddressSpace));
	}
}
예제 #12
0
void InsLibFreeVmeSpace(InsLibVmeAddressSpace *vmeas)
{
	if (vmeas) {
		InsLibFreeVmeSpace(vmeas->Next);
		sysfree((char *) vmeas, sizeof(InsLibVmeAddressSpace));
	}
}
예제 #13
0
파일: flash_emu.c 프로젝트: Julia117/embox
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;
}
예제 #14
0
/**
 * @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 */
}
예제 #15
0
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;
}
예제 #16
0
void InsLibFreeDriver(InsLibDrvrDesc *drvrd)
{
	if (drvrd) {
		InsLibFreeDriver(drvrd->Next);
		InsLibFreeModule(drvrd->Modules);
		sysfree((char *) drvrd, sizeof(InsLibDrvrDesc));
	}
}
예제 #17
0
파일: mtt-skel.c 프로젝트: bradomyn/coht
void SkelUserModuleRelease(SkelDrvrModuleContext *mcon)
{
	/* quiesce the module before it gets uninstalled */
	__mtt_quiesce(mcon);

	/* free userdata */
	sysfree(mcon->UserData, sizeof(struct udata));
}
예제 #18
0
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));
	}
}
예제 #19
0
파일: mtt-skel.c 프로젝트: bradomyn/coht
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;
}
예제 #20
0
파일: mtt-skel.c 프로젝트: bradomyn/coht
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;
}
예제 #21
0
파일: skb.c 프로젝트: mdigiorgio/embox
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);
}
예제 #22
0
파일: mtt-skel.c 프로젝트: bradomyn/coht
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;
}
예제 #23
0
파일: ext3.c 프로젝트: kandeshvari/embox
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;
}
예제 #24
0
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;
}
예제 #25
0
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;
}
예제 #26
0
// 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();
}
예제 #27
0
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;
}
예제 #28
0
// . 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;
}
예제 #29
0
/**
 * @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 */
}
예제 #30
0
void jffs2_free_inode_cache(struct jffs2_inode_cache *x) {
    D1(printk(KERN_DEBUG "Freeing inocache at %p\n", x));
    sysfree(x);
}