Exemplo n.º 1
0
GC gc_cache_lookup(struct gc_cache *cache, XGCValues * gcv, unsigned long mask)
{
	struct gc_cache_cell *cell = NULL, *next = NULL, *prev = NULL;
	struct gcv_and_mask gcvm;

	if (cache == NULL)
		abort();
	else if ((!!cache->head) != (!!cache->tail))
		abort();
	else if (cache->head && cache->tail && (cache->head->prev || cache->tail->next))
		abort();
	else {
		gcvm.mask = mask;
		gcvm.gcv = *gcv;	/* this copies... */

#ifdef GCCACHE_HASH

		if (gethash(&gcvm, cache->table,
			    (const void **)((void*)&cell)))
#else				/* !GCCACHE_HASH */

		/* start at the end (most recently used) */
		cell = cache->tail;
		while (cell) {
			if (gc_cache_eql(&gcvm, &cell->gcvm))
				break;
			else
				cell = cell->prev;
		}

		/* #### This whole file needs some serious overhauling. */
		if (!(mask | GCTile) && cell->gc->values.tile)
			cell = NULL;
		else if (!(mask | GCStipple) && cell->gc->values.stipple)
			cell = NULL;
#endif				/* !GCCACHE_HASH */

		{
			/* Found a cell.  Move this cell to the end of
			   the list, so that it will be less likely to
			   be collected than a cell that was accessed
			   less recently.
			*/

			if (!cell) {
				abort();
				return NULL;
			} else {
				if (cell == cache->tail)
					return cell->gc;
				next = cell->next;
				prev = cell->prev;
				if (prev)
					prev->next = next;
				if (next)
					next->prev = prev;
				if (cache->head == cell)
					cache->head = next;
				cell->next = NULL;
				cell->prev = cache->tail;
				if (cache->tail)
					cache->tail->next = cell;
				else
					abort();
				cache->tail = cell;
				if (cache->head == cell)
					abort();
				else if (cell->next)
					abort();
				else if (cache->head != NULL && cache->head->prev)
					abort();
				else if (cache->tail != NULL && cache->tail->next)
					abort();
				return cell->gc;
			}
		}

		/* else, cache miss. */
		if (cache == NULL)
			abort();
		else if (cache->size == GC_CACHE_SIZE)
			/* Reuse the first cell on the list
			   (least-recently-used).  Remove it from the
			   list, and unhash it from the table.
			*/
		{
			cell = cache->head;
			if (cache->head != NULL) {
				cache->head = cell->next;
				cache->head->prev = 0;
			}
			if (cache->tail == cell)
				cache->tail = 0;	/* only one */
			XFreeGC(cache->dpy, cell->gc);
			cache->delete_count++;
#ifdef GCCACHE_HASH
			remhash(&cell->gcvm, cache->table);
#endif
		} else if (cache->size > GC_CACHE_SIZE)
			abort();
		else {
			/* Allocate a new cell (don't put it in the
			   list or table yet). */
			cell = xnew(struct gc_cache_cell);
			cache->size++;
		}
		if (cell != NULL) {
			/* Now we've got a cell (new or reused).  Fill
			   it in. */
			memcpy(&cell->gcvm.gcv, gcv, sizeof(XGCValues));
			cell->gcvm.mask = mask;

			/* Put the cell on the end of the list. */
			cell->next = 0;
			cell->prev = cache->tail;
			if (cache->tail)
				cache->tail->next = cell;
			cache->tail = cell;
			if (!cache->head)
				cache->head = cell;
			cache->create_count++;
#ifdef GCCACHE_HASH
			/* Hash it in the table */
			puthash(&cell->gcvm, cell, cache->table);
#endif
			/* Now make and return the GC. */
			cell->gc = XCreateGC(cache->dpy, cache->window,
					     mask, gcv);
			/* debug */
			assert(cell->gc == gc_cache_lookup(cache, gcv, mask));
			return cell->gc;
		}
	}
	return NULL; /* No cell determined */
}
Exemplo n.º 2
0
static void
check_free (void *ptr)
{
  __free_hook = 0;
  __malloc_hook = 0;
  if (!pointer_table)
    pointer_table = make_hash_table (max (100, FREE_QUEUE_LIMIT * 2));
  if (ptr != 0)
    {
      long size;
#ifdef UNMAPPED_FREE
      unsigned long rounded_up_size;
#endif

      EMACS_INT present = (EMACS_INT) gethash (ptr, pointer_table,
					       (const void **)
					       (void *) &size);

      if (!present)
	{
	/* This can only happen if you try to free something that didn't
	   come from malloc */
#if !defined(__linux__)
	  /* I originally wrote:  "There's really no need to drop core."
	     I have seen the error of my ways. -slb */
	  assert (!strict_free_check);
#endif
	  printf("Freeing unmalloc'ed memory at %p\n", ptr);
	  __free_hook = check_free;
	  __malloc_hook = check_malloc;
	  goto end;
	}

      if (size < 0)
	{
	  /* This happens when you free twice */
#if !defined(__linux__)
	  /* See above comment. */
	  assert (!strict_free_check);
#endif
	  printf("Freeing %p twice\n", ptr);
	  __free_hook = check_free;
	  __malloc_hook = check_malloc;
	  goto end;
	}

      puthash (ptr, (void *)-size, pointer_table);
#ifdef UNMAPPED_FREE
      /* Round up size to an even number of pages. */
      rounded_up_size = ROUND_UP_TO_PAGE (size);
      /* Protect the pages freed from all access */
      if (strict_free_check)
	mprotect (ptr, rounded_up_size, PROT_NONE);
#else
      /* Set every word in the block to 0xDEADBEEF */
      if (strict_free_check)
	{
	  unsigned long long_length = (size + (sizeof (long) - 1))
	    / sizeof (long);
	  unsigned long i;

          /* Not using the DEADBEEF_CONSTANT #define, since we don't know
           * that allocation sizes will be multiples of eight. */
	  for (i = 0; i < long_length; i++)
	    ((unsigned long *) ptr)[i] = 0xDEADBEEF;
	}
#endif
      free_queue[current_free].address = ptr;
      free_queue[current_free].length = size;

      current_free++;
      if (current_free >= FREE_QUEUE_LIMIT)
	current_free = 0;
      /* Really free this if there's something there */
      {
	void *old = free_queue[current_free].address;

	if (old)
	  {
#ifdef UNMAPPED_FREE
	    unsigned long old_len = free_queue[current_free].length;

	    mprotect (old, old_len,  PROT_READ | PROT_WRITE | PROT_EXEC);
#endif
	    free (old);
	    remhash (old, pointer_table);
	  }
      }
    }
  __free_hook = check_free;
  __malloc_hook = check_malloc;

 end:
  return;
}
Exemplo n.º 3
0
MYBOOL __WINAPI read_params(lprec *lp, char *filename, char *options)
{
    int ret, looping, line;
    FILE *fp;
    hashtable *hashfunctions, *hashparameters;
    hashelem *hp;
    int i, j, elements, n, intvalue, state = 0;
    REAL REALvalue;
    char buf[4096], *header = NULL, *ptr, *ptr1, *ptr2;

    if((fp = ini_open(filename)) == NULL)
        ret = FALSE;
    else {
        /* create hashtable of all callable commands to find them quickly */
        hashfunctions = create_hash_table(sizeof(functions) / sizeof(*functions), 0);
        for (n = 0, i = 0; i < (int) (sizeof(functions)/sizeof(*functions)); i++) {
            puthash(functions[i].par, i, NULL, hashfunctions);
            if(functions[i].values != NULL)
                n += functions[i].elements;
        }
        /* create hashtable of all arguments to find them quickly */
        hashparameters = create_hash_table(n, 0);
        for (n = 0, i = 0; i < (int) (sizeof(functions)/sizeof(*functions)); i++) {
            if(functions[i].values != NULL) {
                elements = functions[i].elements;
                for(j = 0; j < elements; j++)
                    if((strcmp(functions[i].values[j].svalue, "0") != 0) &&
                            (strcmp(functions[i].values[j].svalue, "1") != 0))
                        puthash(functions[i].values[j].svalue, j, NULL, hashparameters);
            }
        }

        readoptions(options, &header);

        STRUPR(header);
        ret = looping = TRUE;
        line = 0;
        while((ret) && (looping)) {
            line++;
            switch(ini_readdata(fp, buf, sizeof(buf), FALSE)) {
            case 0: /* End of file */
                looping = FALSE;
                break;
            case 1: /* header */
                switch(state) {
                case 0:
                    STRUPR(buf);
                    if(strcmp(buf, header) == 0)
                        state = 1;
                    break;
                case 1:
                    looping = FALSE;
                    break;
                }
                break;
            case 2: /* data */
                if(state == 1) {
                    for(ptr = buf; (*ptr) && (isspace(*ptr)); ptr++);
                }
                else
                    ptr = NULL;
                if((ptr != NULL) && (*ptr)) {
                    STRUPR(buf);
                    ptr = strchr(buf, '=');
                    if(ptr == NULL) {
                        report(lp, IMPORTANT, "read_params: No equal sign on line %d\n", line);
                        ret = FALSE;
                    }
                    else {
                        *ptr = 0;
                        for(ptr1 = buf; isspace(*ptr1); ptr1++);
                        for(ptr2 = ptr - 1; (ptr2 >= ptr1) && (isspace(*ptr2)); ptr2--);
                        if(ptr2 <= ptr1) {
                            report(lp, IMPORTANT, "read_params: No parameter name before equal sign on line %d\n", line);
                            ret = FALSE;
                        }
                        else {
                            ptr2[1] = 0;
                            hp = findhash(ptr1, hashfunctions);
                            if(hp == NULL) {
                                report(lp, IMPORTANT, "read_params: Unknown parameter name (%s) before equal sign on line %d\n", ptr1, line);
                                ret = FALSE;
                            }
                            else {
                                i = hp->index;
                                ptr1 = ++ptr;
                                intvalue = 0;
                                REALvalue = 0;
                                if(functions[i].values == NULL) {
                                    switch(functions[i].type) {
                                    case intfunction:
                                    case longfunction:
                                    case MYBOOLfunction:
                                        intvalue = strtol(ptr1, &ptr2, 10);
                                        while((*ptr2) && (isspace(*ptr2)))
                                            ptr2++;
                                        if(*ptr2) {
                                            report(lp, IMPORTANT, "read_params: Invalid integer value on line %d\n", line);
                                            ret = FALSE;
                                        }
                                        break;
                                    case REALfunction:
                                        REALvalue = strtod(ptr1, &ptr2);
                                        while((*ptr2) && (isspace(*ptr2)))
                                            ptr2++;
                                        if(*ptr2) {
                                            report(lp, IMPORTANT, "read_params: Invalid real value on line %d\n", line);
                                            ret = FALSE;
                                        }
                                        break;
                                    }
                                }
                                else {
                                    while(ret) {
                                        ptr = strchr(ptr1, '+');
                                        if(ptr == NULL)
                                            ptr = ptr1 + strlen(ptr1);
                                        for(; isspace(*ptr1); ptr1++);
                                        for(ptr2 = ptr - 1; (ptr2 >= ptr1) && (isspace(*ptr2)); ptr2--);
                                        if(ptr2 <= ptr1)
                                            break;
                                        else {
                                            ptr2[1] = 0;
                                            hp = findhash(ptr1, hashparameters);
                                            if (hp == NULL) {
                                                report(lp, IMPORTANT, "read_params: Invalid parameter name (%s) on line %d\n", ptr1, line);
                                                ret = FALSE;
                                            }
                                            else {
                                                j = hp->index;
                                                if((j >= functions[i].elements) ||
                                                        (strcmp(functions[i].values[j].svalue, ptr1))) {
                                                    report(lp, IMPORTANT, "read_params: Inappropriate parameter name (%s) on line %d\n", ptr1, line);
                                                    ret = FALSE;
                                                }
                                                else {
                                                    intvalue += functions[i].values[j].value;
                                                }
                                            }
                                            ptr1 = ptr + 1;
                                        }
                                    }
                                }
                                if(ret) {
                                    switch(functions[i].type) {
                                    case intfunction:
                                        functions[i].set_function.int_set_function(lp, intvalue);
                                        break;
                                    case longfunction:
                                        functions[i].set_function.long_set_function(lp, intvalue);
                                        break;
                                    case MYBOOLfunction:
                                        functions[i].set_function.MYBOOL_set_function(lp, (MYBOOL) intvalue);
                                        break;
                                    case REALfunction:
                                        functions[i].set_function.REAL_set_function(lp, REALvalue);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                break;
            }
        }

        FREE(header);
        free_hash_table(hashfunctions);
        free_hash_table(hashparameters);

        ini_close(fp);
    }

    return( (MYBOOL) ret );
}