示例#1
0
// Tortuous route to get here!
// m_HotKey looses focus and calls parent (CListCtrl) that calls here
void COptionsShortcuts::OnHotKeyKillFocus(const int item, const UINT id,
                                          const WORD wVirtualKeyCode, 
                                          const WORD wModifiers)
{
  CString str(L"");
  CString cs_warning;
  MapMenuShortcutsIter iter, inuse_iter;
  st_MenuShortcut st_mst;

  st_mst.siVirtKey  = wVirtualKeyCode;
  st_mst.cModifier = wVirtualKeyCode == 0 ? 0 : (unsigned char)wModifiers;

  // Stop compiler complaining - put this here even if not needed
  already_inuse inuse(st_mst);

  if (!CMenuShortcut::IsNormalShortcut(st_mst)) {
    // Invalid shortcut
    cs_warning.LoadString(IDS_SHCT_WARNING1);
    goto set_warning;
  }

  str = CMenuShortcut::FormatShortcut(st_mst);

  if (std::find_if(m_ReservedShortcuts.begin(),
                   m_ReservedShortcuts.end(),
                   reserved(st_mst)) != m_ReservedShortcuts.end()) {
    // Reserved shortcut ignored
    cs_warning.Format(IDS_SHCT_WARNING2, str);
    goto set_warning;
  }

  // Check not already in use (ignore if deleting current shortcut)
  iter = m_MapMenuShortcuts.find(id);
  if (st_mst.siVirtKey != 0) {
    inuse_iter = std::find_if(m_MapMenuShortcuts.begin(),
                              m_MapMenuShortcuts.end(),
                              inuse);
    if (inuse_iter != m_MapMenuShortcuts.end() && 
        inuse_iter->first != iter->first) {
      // Shortcut in use
      cs_warning.Format(IDS_SHCT_WARNING3, str, inuse_iter->second.name.c_str());
      goto set_warning;
    }
  }

  // Not reserved and not already in use - implement
  iter->second.siVirtKey = st_mst.siVirtKey;
  iter->second.cModifier = st_mst.cModifier;

  m_ShortcutLC.SetItemText(item, 0, str);  // SHCT_SHORTCUTKEYS
  m_ShortcutLC.RedrawItems(item, item);    // SHCT_MENUITEMTEXT
  m_ShortcutLC.SetColumnWidth(0, m_iColWidth);              // SHCT_SHORTCUTKEYS
  m_ShortcutLC.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER); // SHCT_MENUITEMTEXT
  m_ShortcutLC.UpdateWindow();
  return;

set_warning:
  m_stc_warning.SetWindowText(cs_warning);
  m_stc_warning.ShowWindow(SW_SHOW);
}
示例#2
0
Item::Item( const ItemDesc& id, Core::UOBJ_CLASS uobj_class )
    : UObject( id.objtype, uobj_class ),
      container( nullptr ),
      decayat_gameclock_( 0 ),
      amount_( 1 ),
      slot_index_( 0 ),
      _itemdesc( nullptr ),
      layer( 0 ),
      hp_( id.maxhp )
{
  graphic = id.graphic;
  color = id.color;
  setfacing( id.facing );
  equip_script_ = id.equip_script;
  unequip_script_ = id.unequip_script;
  newbie( id.newbie );
  insured( id.insured );
  movable( id.default_movable() );
  inuse( false );
  invisible( id.invisible );

  ++Core::stateManager.uobjcount.uitem_count;

  // hmm, doesn't quite work right with items created on startup..
  decayat_gameclock_ = Core::read_gameclock() + id.decay_time * 60;
}
示例#3
0
文件: buffer.c 项目: NeilB879/cctools
/* make room for at least n chars */
static int grow(buffer_t * b, size_t n)
{
	size_t used = inuse(b);
	size_t newlen = sizeof(b->initial); /* current buf is always at least as big as b->initial */

	/* simple solution to find next power of 2 */
	while (newlen < used+n) newlen <<= 1;

	/* too big? */
	if (0 < b->max && b->max < newlen) {
		if (used+n <= b->max) {
			/* This handles the case where b->max is not a power of 2. */
			newlen = b->max;
		} else {
			errno = ENOBUFS;
			checkerror(b, 0, 0);
		}
	}

	if (b->buf == b->ubuf.buf || b->buf == b->initial) {
		char *new = malloc(newlen);
		checkerror(b, NULL, new);
		memcpy(new, b->buf, used);
		b->buf = new;
	} else {
int __cdecl fseek (

#endif  /* _MT */

        FILE *str,
        long offset,
        int whence
        )
{


        REG1 FILE *stream;

        _ASSERTE(str != NULL);

        /* Init stream pointer */
        stream = str;

        if ( !inuse(stream) || ((whence != SEEK_SET) && (whence != SEEK_CUR) &&
            (whence != SEEK_END)) ) {
                errno=EINVAL;
                return(-1);
        }

        /* Clear EOF flag */

        stream->_flag &= ~_IOEOF;

        /* If seeking relative to current location, then convert to
           a seek relative to beginning of file.  This accounts for
           buffering, etc. by letting fseek() tell us where we are. */

        if (whence == SEEK_CUR) {
                offset += _ftell_lk(stream);
                whence = SEEK_SET;
        }

        /* Flush buffer as necessary */

        _flush(stream);

        /* If file opened for read/write, clear flags since we don't know
           what the user is going to do next. If the file was opened for
           read access only, decrease _bufsiz so that the next _filbuf
           won't cost quite so much */

        if (stream->_flag & _IORW)
                stream->_flag &= ~(_IOWRT|_IOREAD);
#if !defined (_M_MPPC) && !defined (_M_M68K)
        else if ( (stream->_flag & _IOREAD) && (stream->_flag & _IOMYBUF) &&
                  !(stream->_flag & _IOSETVBUF) )
                stream->_bufsiz = _SMALL_BUFSIZ;
#endif  /* !defined (_M_MPPC) && !defined (_M_M68K) */

        /* Seek to the desired locale and return. */

        return(_lseek(_fileno(stream), offset, whence) == -1L ? -1 : 0);
}
示例#5
0
文件: stdio.c 项目: HarryR/sanos
FILE *freopen(const char *filename, const char *mode, FILE *stream) { 
  if (inuse(stream)) close_file(stream);
  if (open_file(stream, filename, mode) < 0) {
    free(stream);
    return NULL;
  }

  return stream;
}
示例#6
0
int __cdecl _filwbuf (
        FILE *str
        )

{

        REG1 FILE *stream;

        _ASSERTE(str != NULL);

        /* Init pointer to _iob2 entry. */
        stream = str;

        if (!inuse(stream) || stream->_flag & _IOSTRG)
                return(WEOF);

        if (stream->_flag & _IOWRT) {
                stream->_flag |= _IOERR;
                return(WEOF);
        }

        stream->_flag |= _IOREAD;

        /* Get a buffer, if necessary. */

        if (!anybuf(stream))
                _getbuf(stream);
        else
                stream->_ptr = stream->_base;

        stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz);

        if ((stream->_cnt == 0) || (stream->_cnt == 1) || stream->_cnt == -1) {
                stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
                stream->_cnt = 0;
                return(WEOF);
        }

        if (  !(stream->_flag & (_IOWRT|_IORW)) &&
              ((_osfile_safe(_fileno(stream)) & (FTEXT|FEOFLAG)) ==
                (FTEXT|FEOFLAG)) )
                stream->_flag |= _IOCTRLZ;
        /* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and
           if it is our buffer, then this must be the first _filbuf after
           an fseek on a read-access-only stream. Restore _bufsiz to its
           larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call,
           if one is made, will fill the whole buffer. */
        if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag &
              _IOMYBUF) && !(stream->_flag & _IOSETVBUF) )
        {
                stream->_bufsiz = _INTERNAL_BUFSIZ;
        }
        stream->_cnt -= sizeof(wchar_t);
        return (0xffff & *((wchar_t *)(stream->_ptr))++);

}
示例#7
0
errno_t __cdecl _tfreopen_helper(
    FILE** pfile,
    const _TSCHAR* filename,
    const _TSCHAR* mode,
    FILE* str,
    int shflag
) {
    REG1 FILE* stream;
    _VALIDATE_RETURN_ERRCODE((pfile != NULL), EINVAL);
    *pfile = NULL;
    _VALIDATE_RETURN_ERRCODE((filename != NULL), EINVAL);
    _VALIDATE_RETURN_ERRCODE((mode != NULL), EINVAL);
    _VALIDATE_RETURN_ERRCODE((str != NULL), EINVAL);

    /* We deliberately don't hard-validate for emptry strings here. All other invalid
    path strings are treated as runtime errors by the inner code in _open and openfile.
    This is also the appropriate treatment here. Since fopen is the primary access point
    for file strings it might be subjected to direct user input and thus must be robust to
    that rather than aborting. The CRT and OS do not provide any other path validator (because
    WIN32 doesn't allow such things to exist in full generality).
    */
    if (*filename == _T('\0')) {
        errno = EINVAL;
        return errno;
    }

    /* Init stream pointer */
    stream = str;
    _lock_str(stream);

    __try {
        /* If the stream is in use, try to close it. Ignore possible
         * error (ANSI 4.9.5.4). */
        if (inuse(stream)) {
            _fclose_nolock(stream);
        }

        stream->_ptr = stream->_base = NULL;
        stream->_cnt = stream->_flag = 0;
#ifdef _UNICODE
        *pfile = _wopenfile(filename, mode, shflag, stream);
#else  /* _UNICODE */
        *pfile = _openfile(filename, mode, shflag, stream);
#endif  /* _UNICODE */
    } __finally {
        _unlock_str(stream);
    }

    if (*pfile) {
        return 0;
    }

    return errno;
}
int __cdecl _fcloseall (
        void
        )
{
        REG2 int count = 0;

#ifdef _WIN32

        REG1 i;

        _mlock(_IOB_SCAN_LOCK);

        for ( i = 3 ; i < _nstream ; i++ ) {

            if ( __piob[i] != NULL ) {
                /*
                 * if the stream is in use, close it
                 */
                if ( inuse( (FILE *)__piob[i] ) && (fclose( __piob[i] ) !=
                     EOF) )
                        count++;

                /*
                 * if stream is part of a _FILEX we allocated, free it.
                 */
                if ( i >= _IOB_ENTRIES ) {

#if defined (_MT)
                    DeleteCriticalSection( &(((_FILEX *)__piob[i])->lock) );
#endif  /* defined (_MT) */
                    _free_crt( __piob[i] );
                    __piob[i] = NULL;
                }
            }
        }

        _munlock(_IOB_SCAN_LOCK);

#else  /* _WIN32 */
#if defined (_M_MPPC) || defined (_M_M68K)

        REG1 FILE *stream = &_iob[3];

        for (; stream <= _lastiob; stream++)
                if (fclose(stream) != EOF)
                        count++;

#endif  /* defined (_M_MPPC) || defined (_M_M68K) */
#endif  /* _WIN32 */

        return(count);
}
示例#9
0
文件: hooks.c 项目: AdvancedC/glibc
static mchunkptr
internal_function
mem2chunk_check(void* mem, unsigned char **magic_p)
{
  mchunkptr p;
  INTERNAL_SIZE_T sz, c;
  unsigned char magic;

  if(!aligned_OK(mem)) return NULL;
  p = mem2chunk(mem);
  if (!chunk_is_mmapped(p)) {
    /* Must be a chunk in conventional heap memory. */
    int contig = contiguous(&main_arena);
    sz = chunksize(p);
    if((contig &&
	((char*)p<mp_.sbrk_base ||
	 ((char*)p + sz)>=(mp_.sbrk_base+main_arena.system_mem) )) ||
       sz<MINSIZE || sz&MALLOC_ALIGN_MASK || !inuse(p) ||
       ( !prev_inuse(p) && (p->prev_size&MALLOC_ALIGN_MASK ||
			    (contig && (char*)prev_chunk(p)<mp_.sbrk_base) ||
			    next_chunk(prev_chunk(p))!=p) ))
      return NULL;
    magic = MAGICBYTE(p);
    for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
      if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
    }
  } else {
    unsigned long offset, page_mask = GLRO(dl_pagesize)-1;

    /* mmap()ed chunks have MALLOC_ALIGNMENT or higher power-of-two
       alignment relative to the beginning of a page.  Check this
       first. */
    offset = (unsigned long)mem & page_mask;
    if((offset!=MALLOC_ALIGNMENT && offset!=0 && offset!=0x10 &&
	offset!=0x20 && offset!=0x40 && offset!=0x80 && offset!=0x100 &&
	offset!=0x200 && offset!=0x400 && offset!=0x800 && offset!=0x1000 &&
	offset<0x2000) ||
       !chunk_is_mmapped(p) || (p->size & PREV_INUSE) ||
       ( (((unsigned long)p - p->prev_size) & page_mask) != 0 ) ||
       ( (sz = chunksize(p)), ((p->prev_size + sz) & page_mask) != 0 ) )
      return NULL;
    magic = MAGICBYTE(p);
    for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
      if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
    }
  }
  ((unsigned char*)p)[sz] ^= 0xFF;
  if (magic_p)
    *magic_p = (unsigned char *)p + sz;
  return p;
}
示例#10
0
文件: _freebuf.c 项目: flychen50/clib
void __cdecl _freebuf (
        REG1 FILE *stream
        )
{
        _ASSERTE(stream != NULL);

        if (inuse(stream) && mbuf(stream))
        {
                _free_crt(stream->_base);

                stream->_flag &= ~(_IOMYBUF | _IOSETVBUF);
                stream->_base = stream->_ptr = NULL;
                stream->_cnt = 0;
        }
}
示例#11
0
void pos_check_unsafe_segment(char *name, mstate av, struct seg_info *head, Void_t *first_chunk)
{
    mchunkptr chunk_ptr;

    chunk_ptr = (mchunkptr)first_chunk;
    while(1)
    {
        //inuse Chunk
	if(inuse(chunk_ptr)){
	    printf("Node Address : %p" , chunk2mem(chunk_ptr));
	    pos_check_unsafe_region(name, av, head, chunk_ptr);
	    printf("\n");
	}
	if(chunk_is_last(chunk_ptr))
	    break;

	chunk_ptr = next_chunk(chunk_ptr);		
    }
}
示例#12
0
void* realloc(void* mem, size_t       bytes)
{
  if (mem == 0) 
    return malloc(bytes);
  else
  {
    size_t       nb      = request2size(bytes);
    mchunkptr    p       = mem2chunk(mem);
    size_t       oldsize = p->size;
    int          room;
    mchunkptr    nxt;

    UPDATE_STATS((++n_reallocs, requested_mem += bytes-oldsize));
    
    /* try to expand (even if already big enough), to clean up chunk */

    while (!inuse(nxt = next_chunk(p)))
    {
      UPDATE_STATS ((malloced_mem += nxt->size, ++n_consol));
      unlink(nxt);
      set_size(p, p->size + nxt->size);
    }

    room = p->size - nb;
    if (room >= 0)
    {
      split(p, nb);
      UPDATE_STATS(malloced_mem -= room);
      return chunk2mem(p);
    }
    else /* do the obvious */
    {
      void* newmem;
      set_inuse(p);    /* don't let malloc consolidate us yet! */
      newmem = malloc(nb);
      bcopy(mem, newmem, oldsize - SIZE_SZ);
      free(mem);
      UPDATE_STATS(++n_reallocs_with_copy);
      return newmem;
    }
  }
}
示例#13
0
static int __cdecl flsall (
        int flushflag
        )
{
        REG1 FILE *stream = _iob;
        REG2 int count = 0;
        int errcode = 0;

        for (; stream <= _lastiob; stream++) {

                if ( (flushflag == FLUSHALL) && inuse(stream) ) {
                        /* FLUSHALL functionality: fflush the read or write
                         * stream and, if successful, update the count of
                         * flushed streams
                         */
                        if ( fflush(stream) != EOF )
                                /* update count of successfully flushed
                                 * streams
                                 */
                                count++;
                }
                else if ( (flushflag == FFLUSHNULL) &&
                (stream->_flag & _IOWRT) ) {
                        /* FFLUSHNULL functionality: fflush the write stream
                         * and kept track of the error, if one occurs
                         */
                        if ( fflush(stream) == EOF )
                                errcode = EOF;
                }

        }

        if ( flushflag == FLUSHALL )
                return(count);
        else
                return(errcode);
}
示例#14
0
////////////////////////////////////////
// WARNING!: pos_realloc has error!. FIX UP!
////////////////////////////////////////
Void_t*
pos_int_realloc(char *name, mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
	     INTERNAL_SIZE_T nb)
{
	mchunkptr newp;				/* chunk to return */
	INTERNAL_SIZE_T newsize;		/* its size */
	Void_t* newmem;				/* corresponding user mem */

	mchunkptr next;				/* next contiguous chunk after oldp */

	mchunkptr remainder;			/* extra space at end of newp */
	unsigned long remainder_size;	/* its size */

	mchunkptr bck;				/* misc temp for linking */
	mchunkptr fwd;				/* misc temp for linking */

	unsigned long copysize;		/* bytes to copy */
	unsigned int ncopies;			/* INTERNAL_SIZE_T words to copy */
	INTERNAL_SIZE_T* s;			/* copy source */
	INTERNAL_SIZE_T* d;			/* copy destination */

	const char *errstr = NULL;


	/* oldmem size */
	/*if (oldp->size <= 2 * SIZE_SZ || oldsize >= av->system_mem) {
		errstr = "realloc(): invalid old size";
errout:
		malloc_printerr (check_action, errstr, chunk2mem(oldp));
		return NULL;
	}*/

	next = chunk_at_offset(oldp, oldsize);
	INTERNAL_SIZE_T nextsize = chunksize(next);
	/*if (next->size <= 2 * SIZE_SZ || nextsize >= av->system_mem) {
		errstr = "realloc(): invalid next size";
			goto errout;
	}*/

	//old size 보다 작을 경우
	if ((unsigned long)(oldsize) >= (unsigned long)(nb)) {
		/* already big enough; split below */
		newp = oldp;
		newsize = oldsize;
	}

	//old size 보다 클 경우
	else {

		/* Try to expand forward into next chunk;  split off remainder below */
		if (!inuse(next) &&
			(unsigned long)(newsize = oldsize + nextsize) >= (unsigned long)(nb)) {
			newp = oldp;
			unlink(next, bck, fwd);
		}

		/* allocate, copy, free */
		else {
			newmem = pos_int_malloc(name, av, nb - MALLOC_ALIGN_MASK);
			if (newmem == 0)
				return 0; /* propagate failure */

			newp = mem2chunk(newmem);
			newsize = chunksize(newp);

			/*
			  Avoid copy if newp is next chunk after oldp.
			*/
			if (newp == next) {
				newsize += oldsize;
				newp = oldp;
			}
			else {
				/*
				  Unroll copy of <= 36 bytes (72 if 8byte sizes)
				  We know that contents have an odd number of
				  INTERNAL_SIZE_T-sized words; minimally 3.
				*/

				copysize = oldsize - SIZE_SZ;
				s = (INTERNAL_SIZE_T*)(chunk2mem(oldp));
				d = (INTERNAL_SIZE_T*)(newmem);
				ncopies = copysize / sizeof(INTERNAL_SIZE_T);

				if (ncopies > 9)
					memcpy(d, s, copysize);
				else {
					*(d+0) = *(s+0);
					*(d+1) = *(s+1);
					*(d+2) = *(s+2);
					if (ncopies > 4) {
						*(d+3) = *(s+3);
						*(d+4) = *(s+4);
						if (ncopies > 6) {
							*(d+5) = *(s+5);
							*(d+6) = *(s+6);
							if (ncopies > 8) {
								*(d+7) = *(s+7);
								*(d+8) = *(s+8);
							}
						}
					}
				}

				pos_int_free(name, av, oldp, 1);

				return chunk2mem(newp);
			}
		}
	}

	/* If possible, free extra space in old or extended chunk */

	remainder_size = newsize - nb;

	if (remainder_size < MINSIZE) { /* not enough extra to split off */
		set_head_size(newp, newsize);
		set_inuse_bit_at_offset(newp, newsize);
	}
	else { /* split remainder */
		remainder = chunk_at_offset(newp, nb);

		if (chunk_is_last(newp))
			set_head(remainder, remainder_size | LAST_CHUNK | PREV_INUSE);
		else
			set_head(remainder, remainder_size | PREV_INUSE);

		// set PREV_INUSE flag..
		if (chunk_is_first(newp))
			set_head(newp, nb | FIRST_CHUNK | PREV_INUSE);
		else
			set_head(newp, nb | PREV_INUSE);
		
		//set_head_size(newp, nb);
		//set_head(remainder, remainder_size | PREV_INUSE |(av != &main_arena ? NON_MAIN_ARENA : 0));

		/* Mark remainder as inuse so free() won't complain */
		set_inuse_bit_at_offset(remainder, remainder_size);
		pos_int_free(name, av, remainder, 1);
	}

	return chunk2mem(newp);
}
示例#15
0
/* ------------------------------ realloc ------------------------------ */
void* ulibc_realloc(void* oldmem, size_t bytes)
{
    mstate av;

    size_t  nb;              /* padded request size */

    mchunkptr        oldp;            /* chunk corresponding to oldmem */
    size_t  oldsize;         /* its size */

    mchunkptr        newp;            /* chunk to return */
    size_t  newsize;         /* its size */
    void*          newmem;          /* corresponding user mem */

    mchunkptr        next;            /* next contiguous chunk after oldp */

    mchunkptr        remainder;       /* extra space at end of newp */
    unsigned long     remainder_size;  /* its size */

    mchunkptr        bck;             /* misc temp for linking */
    mchunkptr        fwd;             /* misc temp for linking */

    unsigned long     copysize;        /* bytes to copy */
    unsigned int     ncopies;         /* size_t words to copy */
    size_t* s;               /* copy source */
    size_t* d;               /* copy destination */

    void *retval;

    /* Check for special cases.  */
    if (! oldmem)
	return ulibc_malloc(bytes);
    if (! bytes) {
	ulibc_free (oldmem);
	return NULL;
    }

    av = get_malloc_state();
    checked_request2size(bytes, nb);

    oldp    = mem2chunk(oldmem);
    oldsize = chunksize(oldp);

    check_inuse_chunk(oldp);

    if (!chunk_is_mmapped(oldp)) {

	if ((unsigned long)(oldsize) >= (unsigned long)(nb)) {
	    /* already big enough; split below */
	    newp = oldp;
	    newsize = oldsize;
	}

	else {
	    next = chunk_at_offset(oldp, oldsize);

	    /* Try to expand forward into top */
	    if (next == av->top &&
		    (unsigned long)(newsize = oldsize + chunksize(next)) >=
		    (unsigned long)(nb + MINSIZE)) {
		set_head_size(oldp, nb);
		av->top = chunk_at_offset(oldp, nb);
		set_head(av->top, (newsize - nb) | PREV_INUSE);
		retval = chunk2mem(oldp);
		goto DONE;
	    }

	    /* Try to expand forward into next chunk;  split off remainder below */
	    else if (next != av->top &&
		    !inuse(next) &&
		    (unsigned long)(newsize = oldsize + chunksize(next)) >=
		    (unsigned long)(nb)) {
		newp = oldp;
		unlink(next, bck, fwd);
	    }

	    /* allocate, copy, free */
	    else {
		newmem = malloc(nb - MALLOC_ALIGN_MASK);
		if (newmem == 0) {
		    retval = 0; /* propagate failure */
		    goto DONE;
		}

		newp = mem2chunk(newmem);
		newsize = chunksize(newp);

		/*
		   Avoid copy if newp is next chunk after oldp.
		   */
		if (newp == next) {
		    newsize += oldsize;
		    newp = oldp;
		}
		else {
		    /*
		       Unroll copy of <= 36 bytes (72 if 8byte sizes)
		       We know that contents have an odd number of
		       size_t-sized words; minimally 3.
		       */

		    copysize = oldsize - (sizeof(size_t));
		    s = (size_t*)(oldmem);
		    d = (size_t*)(newmem);
		    ncopies = copysize / sizeof(size_t);
		    assert(ncopies >= 3);

		    if (ncopies > 9)
			memcpy(d, s, copysize);

		    else {
			*(d+0) = *(s+0);
			*(d+1) = *(s+1);
			*(d+2) = *(s+2);
			if (ncopies > 4) {
			    *(d+3) = *(s+3);
			    *(d+4) = *(s+4);
			    if (ncopies > 6) {
				*(d+5) = *(s+5);
				*(d+6) = *(s+6);
				if (ncopies > 8) {
				    *(d+7) = *(s+7);
				    *(d+8) = *(s+8);
				}
			    }
			}
		    }

		    ulibc_free(oldmem);
		    check_inuse_chunk(newp);
		    retval = chunk2mem(newp);
		    goto DONE;
		}
	    }
	}

	/* If possible, free extra space in old or extended chunk */

	assert((unsigned long)(newsize) >= (unsigned long)(nb));

	remainder_size = newsize - nb;

	if (remainder_size < MINSIZE) { /* not enough extra to split off */
	    set_head_size(newp, newsize);
	    set_inuse_bit_at_offset(newp, newsize);
	}
	else { /* split remainder */
	    remainder = chunk_at_offset(newp, nb);
	    set_head_size(newp, nb);
	    set_head(remainder, remainder_size | PREV_INUSE);
	    /* Mark remainder as inuse so free() won't complain */
	    set_inuse_bit_at_offset(remainder, remainder_size);
	    ulibc_free(chunk2mem(remainder));
	}

	check_inuse_chunk(newp);
	retval = chunk2mem(newp);
	goto DONE;
    }

    /*
       Handle mmap cases
       */

    else {
	size_t offset = oldp->prev_size;
	size_t pagemask = av->pagesize - 1;
	char *cp;
	unsigned long  sum;

	/* Note the extra (sizeof(size_t)) overhead */
	newsize = (nb + offset + (sizeof(size_t)) + pagemask) & ~pagemask;

	/* don't need to remap if still within same page */
	if (oldsize == newsize - offset) {
	    retval = oldmem;
	    goto DONE;
	}

	cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1);

	if (cp != (char*)MORECORE_FAILURE) {

	    newp = (mchunkptr)(cp + offset);
	    set_head(newp, (newsize - offset)|IS_MMAPPED);

	    assert(aligned_OK(chunk2mem(newp)));
	    assert((newp->prev_size == offset));

	    /* update statistics */
	    sum = av->mmapped_mem += newsize - oldsize;
	    if (sum > (unsigned long)(av->max_mmapped_mem))
		av->max_mmapped_mem = sum;
	    sum += av->sbrked_mem;
	    if (sum > (unsigned long)(av->max_total_mem))
		av->max_total_mem = sum;

	    retval = chunk2mem(newp);
	    goto DONE;
	}

	/* Note the extra (sizeof(size_t)) overhead. */
	if ((unsigned long)(oldsize) >= (unsigned long)(nb + (sizeof(size_t))))
	    newmem = oldmem; /* do nothing */
	else {
	    /* Must alloc, copy, free. */
	    newmem = malloc(nb - MALLOC_ALIGN_MASK);
	    if (newmem != 0) {
		memcpy(newmem, oldmem, oldsize - 2*(sizeof(size_t)));
		ulibc_free(oldmem);
	    }
	}
	retval = newmem;
    }

 DONE:
    return retval;
}
示例#16
0
/* may be called more than once */
int
ne2000reset(Ether* ether)
{
	ushort buf[16];
	ulong port;
	Dp8390 *ctlr;
	int i;
	uchar ea[Eaddrlen];

	if(ether->port == 0)
		ne2000pnp(ether);

	/*
	 * port == 0 is a desperate attempt to find something at the
	 * default port.  only allow one of these to be found, and
	 * only if no other card has been found.
	 */
	if(ether->port == 0 && ether->ctlrno > 0)
		return -1;
	/*
	 * Set up the software configuration.
	 * Use defaults for port, irq, mem and size
	 * if not specified.
	 */
	if(ether->port == 0)
		ether->port = 0x300;
	if(ether->irq == 0)
		ether->irq = 2;
	if(ether->mem == 0)
		ether->mem = 0x4000;
	if(ether->size == 0)
		ether->size = 16*1024;
	port = ether->port;

	if(inuse(ether->port))
		return -1;

	ether->ctlr = malloc(sizeof(Dp8390));
	ctlr = ether->ctlr;
	ctlr->width = 2;
	ctlr->ram = 0;

	ctlr->port = port;
	ctlr->data = port+Data;

	ctlr->tstart = HOWMANY(ether->mem, Dp8390BufSz);
	ctlr->pstart = ctlr->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
	ctlr->pstop = ctlr->tstart + HOWMANY(ether->size, Dp8390BufSz);

	ctlr->dummyrr = 1;
	for(i = 0; i < ether->nopt; i++){
		if(strcmp(ether->opt[i], "nodummyrr"))
			continue;
		ctlr->dummyrr = 0;
		break;
	}

	/*
	 * Reset the board. This is done by doing a read
	 * followed by a write to the Reset address.
	 */
	buf[0] = inb(port+Reset);
	delay(2);
	outb(port+Reset, buf[0]);
	delay(2);
	
	/*
	 * Init the (possible) chip, then use the (possible)
	 * chip to read the (possible) PROM for ethernet address
	 * and a marker byte.
	 * Could just look at the DP8390 command register after
	 * initialisation has been tried, but that wouldn't be
	 * enough, there are other ethernet boards which could
	 * match.
	 * Parallels has buf[0x0E] == 0x00 whereas real hardware
	 * usually has 0x57.
	 */
	dp8390reset(ether);
	memset(buf, 0, sizeof(buf));
	dp8390read(ctlr, buf, 0, sizeof(buf));
	i = buf[0x0E] & 0xFF;
	if((i != 0x00 && i != 0x57) || (buf[0x0F] & 0xFF) != 0x57){
		free(ether->ctlr);
		return -1;
	}

	/*
	 * Stupid machine. Shorts were asked for,
	 * shorts were delivered, although the PROM is a byte array.
	 * Set the ethernet address.
	 */
	memset(ea, 0, Eaddrlen);
	if(memcmp(ea, ether->ea, Eaddrlen) == 0){
		for(i = 0; i < sizeof(ether->ea); i++)
			ether->ea[i] = buf[i];
	}
	dp8390setea(ether);
	return 0;
}
示例#17
0
FILE * __cdecl _getstream (
    void
    )
{
    FILE *retval = NULL;
    int i;

    /* Get the iob[] scan lock */
    _mlock(_IOB_SCAN_LOCK);
    __try {

        /*
        * Loop through the __piob table looking for a free stream, or the
        * first NULL entry.
        */
        for ( i = 0 ; i < _nstream ; i++ ) {

            if ( __piob[i] != NULL ) {
                /*
                * if the stream is not inuse, return it.
                */
                if ( !inuse( (FILE *)__piob[i] ) && !str_locked( (FILE *)__piob[i] ) ) {
                    /*
                    * Allocate the FILE lock, in case it hasn't already been
                    * allocated (only necessary for the first _IOB_ENTRIES
                    * locks, not including stdin/stdout/stderr).  Return
                    * failure if lock can't be allocated.
                    */
                    if ( i > 2 && i < _IOB_ENTRIES )
                        if ( !_mtinitlocknum( _STREAM_LOCKS + i ) )
                            break;

                    _lock_str2(i, __piob[i]);

                    if ( inuse( (FILE *)__piob[i] ) ) {
                        _unlock_str2(i, __piob[i]);
                        continue;
                    }
                    retval = (FILE *)__piob[i];
                    break;
                }
            }
            else {
                /*
                * allocate a new _FILEX, set _piob[i] to it and return a
                * pointer to it.
                */
                if ( (__piob[i] = _malloc_crt( sizeof(_FILEX) )) != NULL ) {

                    __crtInitializeCriticalSectionEx(&(((_FILEX *)__piob[i])->lock), _CRT_SPINCOUNT, 0);
                    EnterCriticalSection( &(((_FILEX *)__piob[i])->lock) );
                    retval = (FILE *)__piob[i];
                    retval->_flag = 0;
                }

                break;
            }
        }

        /*
        * Initialize the return stream.
        */
        if ( retval != NULL ) {
            /* make sure that _IOLOCKED is preserved (if set) and zero out the other bits of _flag */
            retval->_flag &= _IOLOCKED;
            retval->_cnt = 0;
            retval->_tmpfname = retval->_ptr = retval->_base = NULL;
            retval->_file = -1;
        }

    }
    __finally {
        _munlock(_IOB_SCAN_LOCK);
    }

    return(retval);
}
示例#18
0
static mchunkptr malloc_find_space(size_t       nb)
{
  mbinptr b;

  /* first, re-adjust max used bin */

  while (malloc_maxbin >= FIRSTBIN && 
         malloc_maxbin->hd.bk == &(malloc_maxbin->hd))
  {
    malloc_maxbin->dirty = 0;
    --malloc_maxbin;
  }

  for (b = malloc_maxbin; b >= FIRSTBIN; --b)
  {
    UPDATE_STATS(++n_malloc_bins);

    if (b->dirty)
    {
      mchunkptr h = &(b->hd);         /* head of list */
      mchunkptr p = h->fd;            /* chunk traverser */

      while (p != h)
      {
        mchunkptr nextp = p->fd;       /* save, in case of relinks */
        int consolidated = 0;          /* only unlink/relink if consolidated */

        mchunkptr t;

        UPDATE_STATS(++n_malloc_chunks);

        while (!inuse(t = prev_chunk(p))) /* consolidate backward */
        {
          if (!consolidated) { consolidated = 1; unlink(p); }
          if (t == nextp) nextp = t->fd;
          unlink(t);
          set_size(t, t->size + p->size);
          p = t;
          UPDATE_STATS (++n_consol);
        }
        
        while (!inuse(t = next_chunk(p))) /* consolidate forward */
        {
          if (!consolidated) { consolidated = 1; unlink(p); }
          if (t == nextp) nextp = t->fd;
          unlink(t);
          set_size(p, p->size + t->size);
          UPDATE_STATS (++n_consol);
        }

       if (consolidated)
       {
          if (p->size >= nb)
          {
            /* make it safe to unlink in malloc */
            UPDATE_STATS(++n_avail);
            p->fd = p->bk = p;
            return p;
          }
          else
            consollink(p);
        }

        p = nextp;

      }

      b->dirty = 0;

    }
  }

  /* nothing available - sbrk some more */

  return malloc_from_sys(nb);
}
示例#19
0
static mchunkptr malloc_from_sys(unsigned nb)
{
  mchunkptr p;
  size_t       sbrk_size;
  int* ip;
  
  /* Minimally, we need to pad with enough space */
  /* to place dummy size/use fields to ends if needed */

  sbrk_size = ((nb + SBRK_UNIT - 1 + SIZE_SZ + SIZE_SZ) 
               / SBRK_UNIT) * SBRK_UNIT;

  ip = (int*)(sbrk(sbrk_size));
  if ((char*)ip == (char*)(-1)) /* sbrk returns -1 on failure */
  {
    return 0;
  }

  UPDATE_STATS ((++n_sbrks, sbrked_mem += sbrk_size));


  if (last_sbrk_end != &ip[-1]) 
  {                             
    /* It's either first time through or someone else called sbrk. */
    /* Arrange end-markers at front & back */

    /* Shouldn't be necessary, but better to be safe */
    while (!aligned_OK(ip)) { ++ip; sbrk_size -= SIZE_SZ; }


    /* Mark the front as in use to prevent merging. */
    /* Note we can get away with only 1 word, not MINSIZE overhead here */

    *ip++ = SIZE_SZ | INUSE;
    
    p = (mchunkptr)ip;
    set_size(p,sbrk_size - (SIZE_SZ + SIZE_SZ)); 
    
  }
  else 
  {
    mchunkptr l;  

    /* We can safely make the header start at end of prev sbrked chunk. */
    /* We will still have space left at the end from a previous call */
    /* to place the end marker, below */

    p = (mchunkptr)(last_sbrk_end);
    set_size(p, sbrk_size);


    /* Even better, maybe we can merge with last fragment: */

    l = prev_chunk(p);
    if (!inuse(l))  
    {
      unlink(l);
      set_size(l, p->size + l->size);
      p = l;
    }

  }

  /* mark the end of sbrked space as in use to prevent merging */

  last_sbrk_end = (int*)((char*)p + p->size);
  *last_sbrk_end = SIZE_SZ | INUSE;

  UPDATE_STATS((++n_avail, ++n_malloc_chunks));

  /* make it safe to unlink in malloc */
  UPDATE_STATS(++n_avail);
  p->fd = p->bk = p;

  return p;
}
示例#20
0
int __cdecl _filwbuf (
	FILE *str
	)

#endif	/* _UNICODE */

{
#ifdef	_NTSUBSET_

	return(_TEOF);

#else	/* ndef _NTSUBSET_ */

	REG1 FILE *stream;

	_ASSERTE(str != NULL);

	/* Init pointer to _iob2 entry. */
	stream = str;

	if (!inuse(stream) || stream->_flag & _IOSTRG)
		return(_TEOF);

	if (stream->_flag & _IOWRT) {
#ifdef	_POSIX_
		errno = EBADF;
#endif
		stream->_flag |= _IOERR;
		return(_TEOF);
	}

	stream->_flag |= _IOREAD;

	/* Get a buffer, if necessary. */

	if (!anybuf(stream))
		_getbuf(stream);
	else
		stream->_ptr = stream->_base;

#ifdef	_POSIX_
	stream->_cnt = read(fileno(stream), stream->_base, stream->_bufsiz);
#else
	stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz);
#endif

#ifndef _UNICODE
	if ((stream->_cnt == 0) || (stream->_cnt == -1)) {
#else /* _UNICODE */
	if ((stream->_cnt == 0) || (stream->_cnt == 1) || stream->_cnt == -1) {
#endif /* _UNICODE */
		stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
		stream->_cnt = 0;
		return(_TEOF);
	}

#ifndef _POSIX_
	if (  !(stream->_flag & (_IOWRT|_IORW)) &&
	      ((_osfile_safe(_fileno(stream)) & (FTEXT|FEOFLAG)) == 
                (FTEXT|FEOFLAG)) )
		stream->_flag |= _IOCTRLZ;
#endif
	/* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and
	   if it is our buffer, then this must be the first _filbuf after
	   an fseek on a read-access-only stream. Restore _bufsiz to its
	   larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call,
	   if one is made, will fill the whole buffer. */
	if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag &
	      _IOMYBUF) && !(stream->_flag & _IOSETVBUF) )
	{
		stream->_bufsiz = _INTERNAL_BUFSIZ;
	}
#ifndef _UNICODE
	stream->_cnt--;
	return(0xff & *stream->_ptr++);
#else	/* _UNICODE */
	stream->_cnt -= sizeof(wchar_t);
	return (0xffff & *((wchar_t *)(stream->_ptr))++);
#endif	/* _UNICODE */

#endif	/* _NTSUBSET_ */
}


#else	/* ndef _WIN32 */

#if	defined(_M_MPPC) || defined(_M_M68K)


#include <cruntime.h>
#include <stdio.h>
#include <file2.h>
#include <io.h>
#include <dbgint.h>
#include <malloc.h>
#include <internal.h>
#include <msdos.h>

/***
*int _filbuf(stream) - fill buffer and get first character
*
*Purpose:
*	get a buffer if the file doesn't have one, read into it, return first
*	char. try to get a buffer, if a user buffer is not assigned. called
*	only from getc; intended for use only within library. assume no input
*	stream is to remain unbuffered when memory is available unless it is
*	marked _IONBF. at worst, give it a single char buffer. the need for a
*	buffer, no matter how small, becomes evident when we consider the
*	ungetc's necessary in scanf
*
*Entry:
*	FILE *stream - stream to read from
*
*Exit:
*	returns first character from buffer (next character to be read)
*	returns EOF if the FILE is actually a string, or not open for reading,
*	or if open for writing or if no more chars to read.
*	all fields in FILE structure may be changed except _file.
*
*Exceptions:
*
*******************************************************************************/

int __cdecl _filbuf (
	FILE *str
	)
{
	REG1 FILE *stream;

	_ASSERTE(str != NULL);

	/* Init pointer to _iob2 entry. */
	stream = str;

	if (!inuse(stream) || stream->_flag & _IOSTRG)
		return(EOF);

	if (stream->_flag & _IOWRT) {
		stream->_flag |= _IOERR;
		return(EOF);
	}

	stream->_flag |= _IOREAD;

	/* Get a buffer, if necessary. */

	if (!anybuf(stream))
		_getbuf(stream);
	else
		stream->_ptr = stream->_base;

	stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz);

	if ((stream->_cnt == 0) || (stream->_cnt == -1)) {
		stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
		stream->_cnt = 0;
		return(EOF);
	}

	if (  !(stream->_flag & (_IOWRT|_IORW)) &&
	((_osfile[_fileno(stream)] & (FTEXT|FEOFLAG)) == (FTEXT|FEOFLAG)) )
		stream->_flag |= _IOCTRLZ;

	stream->_cnt--;

	return(0xff & *stream->_ptr++);
}
示例#21
0
文件: SETMAXF.C 项目: ngphloc/agmagic
int __cdecl _setmaxstdio (
        int maxnum
        )
{
        void **newpiob;
        int i;
        int retval;

        /*
         * Make sure the request is reasonable.
         */
        if ( (maxnum < _IOB_ENTRIES) || (maxnum > _NHANDLE_) )
            return -1;

        _mlock(_IOB_SCAN_LOCK);

        /*
         * Try to reallocate the __piob array.
         */
        if ( maxnum > _nstream ) {
            if ( (newpiob = _realloc_crt( __piob, maxnum * sizeof(void *) ))
                 != NULL )
            {
                /*
                 * Initialize new __piob entries to NULL
                 */
                for ( i = _nstream ; i < maxnum ; i++ )
                    newpiob[i] = NULL;

                retval = _nstream = maxnum;
                __piob = newpiob;
            }
            else
                retval = -1;
        }
        else if ( maxnum == _nstream )
            retval = _nstream;
        else {  /* maxnum < _nstream */
            retval = maxnum;
            /*
             * Clean up the portion of the __piob[] to be freed.
             */
            for ( i = _nstream - 1 ; i >= maxnum ; i-- )
                /*
                 * If __piob[i] is non-NULL, free up the _FILEX struct it
                 * points to.
                 */
                if ( __piob[i] != NULL )
                    if ( !inuse( (FILE *)__piob[i] ) ) {
                        _free_crt( __piob[i] );
                    }
                    else {
                        /*
                         * _FILEX is still inuse! Don't free any anything and
                         * return failure to the caller.
                         */
                        retval = -1;
                        break;
                    }

            if ( retval != -1 )
                if ( (newpiob = _realloc_crt( __piob, maxnum * sizeof(void *) ))
                     != NULL )
                {
                    _nstream = maxnum;      /* retval already set to maxnum */
                    __piob = newpiob;
                }
                else
                    retval = -1;
        }

        _munlock(_IOB_SCAN_LOCK);

        return retval;
}
示例#22
0
文件: _filbuf.c 项目: flychen50/clib
int __cdecl _filwbuf (
        FILE *str
        )

#endif  /* _UNICODE */

{

        REG1 FILE *stream=NULL;

                /* In safecrt, we assume we always have a buffer */
        _VALIDATE_RETURN(str != NULL, EINVAL, _TEOF);

        /* Init pointer to _iob2 entry. */
        stream = str;

        if (!inuse(stream) || stream->_flag & _IOSTRG)
                return(_TEOF);

        if (stream->_flag & _IOWRT) {
                stream->_flag |= _IOERR;
                return(_TEOF);
        }

        stream->_flag |= _IOREAD;

        /* Get a buffer, if necessary. */

        if (!anybuf(stream))
        {
#ifndef _SAFECRT_IMPL
            _getbuf(stream);
#else  /* _SAFECRT_IMPL */
            /* In safecrt, we assume we always have a buffer */
            _VALIDATE_RETURN(FALSE, EINVAL, _TEOF);
#endif  /* _SAFECRT_IMPL */
        }
        else
        {
            stream->_ptr = stream->_base;
        }

        stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz);

#ifndef _UNICODE
        if ((stream->_cnt == 0) || (stream->_cnt == -1)) {
#else  /* _UNICODE */
        if ((stream->_cnt == 0) || (stream->_cnt == 1) || stream->_cnt == -1) {
#endif  /* _UNICODE */
                stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
                stream->_cnt = 0;
                return(_TEOF);
        }

        if (  !(stream->_flag & (_IOWRT|_IORW)) &&
              ((_osfile_safe(_fileno(stream)) & (FTEXT|FEOFLAG)) ==
                (FTEXT|FEOFLAG)) )
                stream->_flag |= _IOCTRLZ;
        /* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and
           if it is our buffer, then this must be the first _filbuf after
           an fseek on a read-access-only stream. Restore _bufsiz to its
           larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call,
           if one is made, will fill the whole buffer. */
        if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag &
              _IOMYBUF) && !(stream->_flag & _IOSETVBUF) )
        {
                stream->_bufsiz = _INTERNAL_BUFSIZ;
        }
#ifndef _UNICODE
        stream->_cnt--;
        return(0xff & *stream->_ptr++);
#else  /* _UNICODE */
        stream->_cnt -= sizeof(wchar_t);
        return (0xffff & *((wchar_t *)(stream->_ptr))++);
#endif  /* _UNICODE */

}
示例#23
0
文件: STREAM.C 项目: ngphloc/agmagic
FILE * __cdecl _getstream (
        void
        )
{
        REG2 FILE *retval = NULL;

#ifdef _WIN32

        REG1 int i;

        /* Get the iob[] scan lock */
        _mlock(_IOB_SCAN_LOCK);

        /*
         * Loop through the __piob table looking for a free stream, or the
         * first NULL entry.
         */
        for ( i = 0 ; i < _nstream ; i++ ) {

            if ( __piob[i] != NULL ) {
                /*
                 * if the stream is not inuse, return it.
                 */
                if ( !inuse( (FILE *)__piob[i] ) ) {
#ifdef _MT
                    _lock_str2(i, __piob[i]);

                    if ( inuse( (FILE *)__piob[i] ) ) {
                        _unlock_str2(i, __piob[i]);
                        continue;
                    }
#endif  /* _MT */
                    retval = (FILE *)__piob[i];
                    break;
                }
            }
            else {
                /*
                 * allocate a new _FILEX, set _piob[i] to it and return a
                 * pointer to it.
                 */
                if ( (__piob[i] = _malloc_crt( sizeof(_FILEX) )) != NULL ) {

#if defined (_MT)
                    InitializeCriticalSection( &(((_FILEX *)__piob[i])->lock) );
                    EnterCriticalSection( &(((_FILEX *)__piob[i])->lock) );
#endif  /* defined (_MT) */
                    retval = (FILE *)__piob[i];
                }

                break;
            }
        }

        /*
         * Initialize the return stream.
         */
        if ( retval != NULL ) {
            retval->_flag = retval->_cnt = 0;
            retval->_tmpfname = retval->_ptr = retval->_base = NULL;
            retval->_file = -1;
        }

        _munlock(_IOB_SCAN_LOCK);

#else  /* _WIN32 */
#if defined (_M_MPPC) || defined (_M_M68K)

        REG1 FILE *stream = _iob;

        /* Loop through the _iob table looking for a free stream.*/
        for (; stream <= _lastiob; stream++) {

                if ( !inuse(stream) ) {
                        stream->_flag = stream->_cnt = 0;
                        stream->_tmpfname = stream->_ptr = stream->_base = NULL;
                        stream->_file = -1;
                        retval = stream;
                        break;
                }
        }

#endif  /* defined (_M_MPPC) || defined (_M_M68K) */
#endif  /* _WIN32 */

        return(retval);
}
示例#24
0
//static void 
void
pos_int_free(char *name, mstate av, mchunkptr p, int flag)
{
	INTERNAL_SIZE_T size;
	mfastbinptr* fb;
	mchunkptr prevchunk;
	INTERNAL_SIZE_T prevsize;
	mchunkptr nextchunk;
	INTERNAL_SIZE_T nextsize;
	int nextinuse;
	mchunkptr bck;
	mchunkptr fwd;

	//const char *errstr = NULL;


	size = chunksize(p);
	/*if ((uintptr_t) p > (uintptr_t) -size || misaligned_chunk (p)) {
		errstr = "free(): invalid pointer";
errout:
		//malloc_printerr (check_action, errstr, chunk2mem(p));
		return;
	}*/
	/*if (size < MINSIZE) {
		errstr = "free(): invalid size";
		goto errout;
	}*/

	//check_inuse_chunk(av, p);


	// fastbin
	if (flag==1 && (unsigned long)(size) <= (unsigned long)(get_max_fast ())) {
		/*if (chunk_at_offset (p, size)->size <= 2 * SIZE_SZ
		   || chunksize (chunk_at_offset (p, size)) >= av->system_mem) {
			errstr = "free(): invalid next size (fast)";
			goto errout;
		}*/

#if CONSISTENCY == 1
		set_fastchunks_log(name, av);
#else
		set_fastchunks(av);
#endif
		fb = &fastbin(av, fastbin_index(size));

		if (*fb == p) {
			//errstr = "double free or corruption (fasttop)";
			//goto errout;
			return ;
		}

#if CONSISTENCY == 1
		POS_WRITE_VAUE(name, (unsigned long *)&p->fd, (unsigned long)*fb);
		POS_WRITE_VAUE(name, (unsigned long *)fb, (unsigned long)p);
#else
		p->fd = *fb;
		*fb = p;
#endif

		return ;
	}

	// 1. First chunk
	if (chunk_is_first(p)) {

		nextchunk = next_chunk(p);
		nextsize = chunksize(nextchunk);

		// 1-1. (free F), free L
		if (chunk_is_last(nextchunk) && !inuse(nextchunk)) {

			//if (av < p && p < (char *)(av+PAGESIZE)){
			if ((char*)av+sizeof(struct malloc_state) == (char*)p) {
#if CONSISTENCY == 1
				insert_to_unsorted_log(name, av, p, bck, fwd, size);

				set_foot_log(name, p, size);
				clear_inuse_bit_at_offset_log(name, p, size);
#else
				insert_to_unsorted(av, p, bck, fwd, size);

				set_foot(p, size);
				clear_inuse_bit_at_offset(p, size);
#endif

				goto out;
			}
			else {
#if CONSISTENCY == 1
				unlink_log(name, nextchunk, bck, fwd);
				size = size + nextsize + 2*SIZE_SZ;

				pos_log_insert_malloc_free(name, (unsigned long)p, size);
				//pos_seg_free(name, (void *)p, size); // Delayed pos_seg_free
				POS_WRITE_VAUE(name, (unsigned long *)&av->system_mem, (unsigned long)(av->system_mem-size));
#else
				unlink(nextchunk, bck, fwd);
				size = size + nextsize + 2*SIZE_SZ;
				/*if (size%PAGESIZE != 0) {
					errstr = "free(): unmmap size is not page size";
					goto errout;
				}*/
				//FREE((char*)p, size);
				pos_seg_free(name, (void *)p, size);
				av->system_mem -= size;
#endif

				goto out;
			}

		}

		// 1-3. (free F), free M
		else if (!inuse(nextchunk)) {
#if CONSISTENCY == 1
			unlink_log(name, nextchunk, bck, fwd);
			size += nextsize;

			insert_to_unsorted_log(name, av, p, bck, fwd, size);

			set_head_log(name, p, size | FIRST_CHUNK | PREV_INUSE);
			set_foot_log(name, p, size);
#else
			unlink(nextchunk, bck, fwd);
			size += nextsize;

			insert_to_unsorted(av, p, bck, fwd, size);

			set_head(p, size | FIRST_CHUNK | PREV_INUSE);
			set_foot(p, size);
#endif

			goto out;
		}

		// 1-2. (free F), inuse L & 1-4. (free F), inuse M
		else {
#if CONSISTENCY == 1
			insert_to_unsorted_log(name, av, p, bck, fwd, size);

			set_foot_log(name, p, size);
			clear_inuse_bit_at_offset_log(name, p, size);
#else
			insert_to_unsorted(av, p, bck, fwd, size);

			set_foot(p, size);
			clear_inuse_bit_at_offset(p, size);
#endif

			goto out;
		}

	}

	// 2. Last chunk
	else if (chunk_is_last(p)) {

		if (!prev_inuse(p)) {
			prevchunk = prev_chunk(p);
			prevsize = chunksize(prevchunk);

			// 2-1. free F, (free L)
			if (chunk_is_first(prevchunk)) {

				//if (av < prevchunk && prevchunk < av+PAGESIZE){
				if((char*)av+sizeof(struct malloc_state) == (char*)prevchunk) {
#if CONSISTENCY == 1
					insert_to_unsorted_log(name, av, p, bck, fwd, size);
  
					set_foot_log(name, p, size);
					clear_inuse_bit_at_offset_log(name, p, size);
#else
					insert_to_unsorted(av, p, bck, fwd, size);
  
					set_foot(p, size);
					clear_inuse_bit_at_offset(p, size);
#endif

					goto out;
				}
				else {
#if CONSISTENCY == 1
					unlink_log(name, prevchunk, bck, fwd);
					size = prevsize+size+2*SIZE_SZ;
					//pos_seg_free(name, (void *)p, size);
					pos_log_insert_malloc_free(name, (unsigned long)p, size);
					POS_WRITE_VAUE(name, (unsigned long *)&av->system_mem, (unsigned long)(av->system_mem-size));
#else
					unlink(prevchunk, bck, fwd);
					size = prevsize+size+2*SIZE_SZ;
					/*if (size%PAGESIZE != 0) {
						errstr = "free(): unmmap size is not page size";
						goto errout;
					}*/
					//FREE((char*)p, size);
					pos_seg_free(name, (void *)p, size);
					av->system_mem -= size;
#endif

					goto out;
				}

			}

			// 2-3. free M, (free L)
			else {
#if CONSISTENCY == 1
				unlink_log(name, prevchunk, bck, fwd);
				size += prevsize;
				p = chunk_at_offset(p, -((long) prevsize));
  
				insert_to_unsorted_log(name, av, p, bck, fwd, size);

				set_head_log(name, p, size | LAST_CHUNK | PREV_INUSE);
				set_foot_log(name, p, size);
				clear_inuse_bit_at_offset_log(name, p, size);
#else
				unlink(prevchunk, bck, fwd);
				size += prevsize;
				p = chunk_at_offset(p, -((long) prevsize));
  
				insert_to_unsorted(av, p, bck, fwd, size);

				set_head(p, size | LAST_CHUNK | PREV_INUSE);
				set_foot(p, size);
				clear_inuse_bit_at_offset(p, size);
#endif
				goto out;
			}

		}

		// 2-2. inuse F, (free L) & 2-4. inuse M, (free L)
		else {
#if CONSISTENCY == 1
			insert_to_unsorted_log(name, av, p, bck, fwd, size);
  
			set_foot_log(name, p, size);
			clear_inuse_bit_at_offset_log(name, p, size);
#else
			insert_to_unsorted(av, p, bck, fwd, size);
  
			set_foot(p, size);
			clear_inuse_bit_at_offset(p, size);
#endif

			goto out;
		}

	}

	// 3. Middle chunk
	else {

		nextchunk = next_chunk(p);
		nextsize = chunksize(nextchunk);

		if (!prev_inuse(p)) {
			prevchunk = prev_chunk(p);
			prevsize = chunksize(prevchunk);

			// 3-1. free F, (free M), free L
			if (chunk_is_first(prevchunk) && chunk_is_last(nextchunk) && !inuse(nextchunk) ) {
	
				//if (av < prevchunk && prevchunk < av+PAGESIZE){
				if((char*)av+sizeof(struct malloc_state) == (char*)prevchunk) {
#if CONSISTENCY == 1
					unlink_log(name, prevchunk, bck, fwd);
					size += prevsize;
					p = chunk_at_offset(p, -((long) prevsize));

					insert_to_unsorted_log(name, av, p, bck, fwd, size);
  
					set_head_log(name, p, size | FIRST_CHUNK | PREV_INUSE);
					set_foot_log(name, p, size);
					clear_inuse_bit_at_offset_log(name, p, size);
#else
					unlink(prevchunk, bck, fwd);
					size += prevsize;
					p = chunk_at_offset(p, -((long) prevsize));

					insert_to_unsorted(av, p, bck, fwd, size);
  
					set_head(p, size | FIRST_CHUNK | PREV_INUSE);
					set_foot(p, size);
					clear_inuse_bit_at_offset(p, size);
  #endif
  
					goto out;
				}

				else {
#if CONSISTENCY == 1
					unlink_log(name, prevchunk, bck, fwd);
					unlink_log(name, nextchunk, bck, fwd);
					p = chunk_at_offset(p, -((long) prevsize));
					size = prevsize+size+nextsize+2*SIZE_SZ;

					pos_log_insert_malloc_free(name, (unsigned long)p, size);
					//pos_seg_free(name, (void *)p, size);
					POS_WRITE_VAUE(name, (unsigned long *)&av->system_mem, (unsigned long)(av->system_mem-size));
#else
					unlink(prevchunk, bck, fwd);
					unlink(nextchunk, bck, fwd);
					p = chunk_at_offset(p, -((long) prevsize));
					size = prevsize+size+nextsize+2*SIZE_SZ;
					/*if (size%PAGESIZE != 0) {
						errstr = "free(): unmmap size is not page size";
						goto errout;
					}*/
					//FREE((char*)p, size);
					pos_seg_free(name, (void *)p, size);
					av->system_mem -= size;
  #endif
  
					goto out;
				}
			}

#if CONSISTENCY == 1
			unlink_log(name, prevchunk, bck, fwd);
#else
			unlink(prevchunk, bck, fwd);
#endif
			size += prevsize;
			p = chunk_at_offset(p, -((long) prevsize));

			if (chunk_is_first(prevchunk)) {
#if CONSISTENCY == 1
				set_head_log(name, p, size | FIRST_CHUNK | PREV_INUSE);
#else
				set_head(p, size | FIRST_CHUNK | PREV_INUSE);
				//set_foot(p, size);
				//clear_inuse_bit_at_offset(p, size);
#endif
			}

		}

		nextinuse = inuse_bit_at_offset(nextchunk, nextsize);

		if (!nextinuse) {
#if CONSISTENCY == 1
			unlink_log(name, nextchunk, bck, fwd);
#else
			unlink(nextchunk, bck, fwd);
#endif
			size += nextsize;
		}

#if CONSISTENCY == 1
		insert_to_unsorted_log(name, av, p, bck, fwd, size);

		if (chunk_is_first(p)) {
			set_head_log(name, p, size | FIRST_CHUNK | PREV_INUSE);
		} else if (chunk_is_last(nextchunk)&&!nextinuse) {
			set_head_log(name, p, size | LAST_CHUNK | PREV_INUSE);
		} else {
			set_head_log(name, p, size | PREV_INUSE);
		}
		set_foot_log(name, p, size);
		clear_inuse_bit_at_offset_log(name, p, size);
#else
		//else
		//clear_inuse_bit_at_offset(nextchunk, 0);

		insert_to_unsorted(av, p, bck, fwd, size);

		if (chunk_is_first(p)) {
			set_head(p, size | FIRST_CHUNK | PREV_INUSE);
		} else if (chunk_is_last(nextchunk)&&!nextinuse) {
			set_head(p, size | LAST_CHUNK | PREV_INUSE);
		} else {
			set_head(p, size | PREV_INUSE);
		}
		set_foot(p, size);
		clear_inuse_bit_at_offset(p, size);

		//check_free_chunk(av, p);
 #endif
	}

out: 
	if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD && have_fastchunks(av)) {
		pos_malloc_consolidate(name, av);
	}
}
示例#25
0
void* malloc(size_t       bytes)
{
  size_t       nb  = request2size(bytes);  /* padded request size */
  mbinptr      b   = size2bin(nb);         /* corresponding bin */
  mchunkptr    hd  = &(b->hd);             /* head of its list */
  mchunkptr    p   = hd->fd;               /* chunk traverser */

  UPDATE_STATS((requested_mem+=bytes, ++n_malloc_bins));

  /* Try a (near) exact match in own bin */
  /* clean out unusable but consolidatable chunks in bin while traversing */

  while (p != hd)
  {
    UPDATE_STATS(++n_malloc_chunks);
    if (p->size >= nb)
      goto found;
    else    /* try to consolidate; same code as malloc_find_space */
    {
      mchunkptr nextp = p->fd;       /* save, in case of relinks */
      int consolidated = 0;          /* only unlink/relink if consolidated */
      
      mchunkptr t;

      while (!inuse(t = prev_chunk(p))) /* consolidate backward */
      {
        if (!consolidated) { consolidated = 1; unlink(p); }
        if (t == nextp) nextp = t->fd;
        unlink(t);
        set_size(t, t->size + p->size);
        p = t;
        UPDATE_STATS (++n_consol);
      }
      
      while (!inuse(t = next_chunk(p))) /* consolidate forward */
      {
        if (!consolidated) { consolidated = 1; unlink(p); }
        if (t == nextp) nextp = t->fd;
        unlink(t);
        set_size(p, p->size + t->size);
        UPDATE_STATS (++n_consol);
      }
      
      if (consolidated)
      {
        if (p->size >= nb)
        {
          /* make it safe to unlink again below */
          UPDATE_STATS(++n_avail);
          p->fd = p->bk = p;
          goto found;
        }
        else
          consollink(p);
      }

      p = nextp;

    }
  }

  b->dirty = 0; /* true if got here */

  /*  Scan bigger bins for a victim */

  while (++b <= malloc_maxbin)
  {
    UPDATE_STATS(++n_malloc_bins);
    if ((p = b->hd.bk) != &(b->hd))    /* no need to check size */
      goto found;
  }

  /* Consolidate or sbrk */

  p = malloc_find_space(nb);

  if (p == 0) return 0; /* allocation failure */

 found:   /* Use what we found */

  unlink(p);
  split(p, nb); 
  UPDATE_STATS(do_malloc_stats(p));
  return chunk2mem(p);
}
示例#26
0
static int __cdecl flsall (
        int flushflag
        )
{
        REG1 int i;
        int count = 0;
        int errcode = 0;

        _mlock(_IOB_SCAN_LOCK);

        for ( i = 0 ; i < _nstream ; i++ ) {

                if ( (__piob[i] != NULL) && (inuse((FILE *)__piob[i])) ) {

#ifdef _MT
                        /*
                         * lock the stream. this is not done until testing
                         * the stream is in use to avoid unnecessarily creating
                         * a lock for every stream. the price is having to
                         * retest the stream after the lock has been asserted.
                         */
                        _lock_str2(i, __piob[i]);

                        /*
                         * if the stream is STILL in use (it may have been
                         * closed before the lock was asserted), see about
                         * flushing it.
                         */
                        if ( inuse((FILE *)__piob[i]) ) {
#endif  /* _MT */

                        if ( flushflag == FLUSHALL ) {
                                /*
                                 * FLUSHALL functionality: fflush the read or
                                 * write stream and, if successful, update the
                                 * count of flushed streams
                                 */
                                if ( _fflush_lk(__piob[i]) != EOF )
                                        /* update count of successfully flushed
                                         * streams
                                         */
                                        count++;
                        }
                        else if ( (flushflag == FFLUSHNULL) &&
                                  (((FILE *)__piob[i])->_flag & _IOWRT) ) {
                                /*
                                 * FFLUSHNULL functionality: fflush the write
                                 * stream and kept track of the error, if one
                                 * occurs
                                 */
                                if ( _fflush_lk(__piob[i]) == EOF )
                                        errcode = EOF;
                        }

#ifdef _MT
                        }
                        _unlock_str2(i, __piob[i]);
#endif  /* _MT */
                }
        }

        _munlock(_IOB_SCAN_LOCK);

        if ( flushflag == FLUSHALL )
                return(count);
        else
                return(errcode);
}