Beispiel #1
0
void hash_insert(struct locked_hash_table *table,
		 unsigned long key, void *value)
{
	pthread_rwlock_wrlock(&table->lock);
	drmHashInsert(table->table, key, value);
	pthread_rwlock_unlock(&table->lock);
}
Beispiel #2
0
drm_public
int drm_tegra_bo_get_name(struct drm_tegra_bo *bo, uint32_t *name)
{
	if (!bo || !name)
		return -EINVAL;

	if (!bo->name) {
		struct drm_gem_flink args;
		int err;

		memset(&args, 0, sizeof(args));
		args.handle = bo->handle;

		err = drmIoctl(bo->drm->fd, DRM_IOCTL_GEM_FLINK, &args);
		if (err < 0) {
			VDBG_BO(bo, "err %d strerror(%s)\n",
				err, strerror(-err));
			return -errno;
		}

		pthread_mutex_lock(&table_lock);

		drmHashInsert(bo->drm->name_table, args.name, bo);
		bo->name = args.name;

		pthread_mutex_unlock(&table_lock);
	}

	*name = bo->name;

	DBG_BO(bo, "\n");

	return 0;
}
Beispiel #3
0
/* allocate a new buffer object, call w/ table_lock held */
static struct etna_bo * bo_from_handle(struct etna_device *dev,
		uint32_t size, uint32_t handle)
{
	unsigned int i;

	struct etna_bo *bo = calloc(sizeof(*bo), 1);
	if (!bo) {
		struct drm_gem_close req = {
				.handle = handle,
		};
		drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
		return NULL;
	}

	for (i = 0; i < ARRAY_SIZE(bo->list); i++)
		list_inithead(&bo->list[i]);

	bo->dev = etna_device_ref(dev);
	bo->size = size;
	bo->handle = handle;
	atomic_set(&bo->refcnt, 1);
	/* add ourselves to the handle table: */
	drmHashInsert(dev->handle_table, handle, bo);
	return bo;
}
Beispiel #4
0
/* allocate a new buffer object, call w/ table_lock held */
static struct omap_bo * bo_from_handle(struct omap_device *dev,
		uint32_t handle)
{
	struct omap_bo *bo = calloc(sizeof(*bo), 1);
	if (!bo) {
		struct drm_gem_close req = {
				.handle = handle,
		};
		drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
		return NULL;
	}
	bo->dev = omap_device_ref(dev);
	bo->handle = handle;
	atomic_set(&bo->refcnt, 1);
	/* add ourselves to the handle table: */
	drmHashInsert(dev->handle_table, handle, bo);
	return bo;
}
Beispiel #5
0
drm_public int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
		      uint32_t handle, uint32_t flags, uint32_t size)
{
	struct drm_tegra_bo *bo;
	int err = 0;

	if (!drm || !bop)
		return -EINVAL;

	pthread_mutex_lock(&table_lock);

	/* check handle table to see if BO is already open */
	bo = lookup_bo(drm->handle_table, handle);
	if (bo)
		goto unlock;

	bo = calloc(1, sizeof(*bo));
	if (!bo) {
		err = -ENOMEM;
		goto unlock;
	}

	DRMINITLISTHEAD(&bo->push_list);
	DRMINITLISTHEAD(&bo->bo_list);
	atomic_set(&bo->ref, 1);
	bo->handle = handle;
	bo->flags = flags;
	bo->size = size;
	bo->drm = drm;

	VG_BO_ALLOC(bo);

	/* add ourselves into the handle table */
	drmHashInsert(drm->handle_table, handle, bo);

	DBG_BO(bo, "success\n");
unlock:
	pthread_mutex_unlock(&table_lock);

	*bop = bo;

	return err;
}
Beispiel #6
0
struct fd_device * fd_device_new(int fd)
{
	struct fd_device *dev = NULL;
	int key = fd;

	pthread_mutex_lock(&table_lock);

	if (!dev_table)
		dev_table = drmHashCreate();

	if (drmHashLookup(dev_table, key, (void **)&dev)) {
		dev = fd_device_new_impl(fd);
		if (dev)
			drmHashInsert(dev_table, key, dev);
	} else {
		dev = fd_device_ref(dev);
	}

	pthread_mutex_unlock(&table_lock);

	return dev;
}
Beispiel #7
0
drm_public struct omap_device * omap_device_new(int fd)
{
	struct omap_device *dev = NULL;

	pthread_mutex_lock(&table_lock);

	if (!dev_table)
		dev_table = drmHashCreate();

	if (drmHashLookup(dev_table, fd, (void **)&dev)) {
		/* not found, create new device */
		dev = omap_device_new_impl(fd);
		drmHashInsert(dev_table, fd, dev);
	} else {
		/* found, just incr refcnt */
		dev = omap_device_ref(dev);
	}

	pthread_mutex_unlock(&table_lock);

	return dev;
}
Beispiel #8
0
/* allocate a new buffer object, call w/ table_lock held */
static struct fd_bo * bo_from_handle(struct fd_device *dev,
		uint32_t size, uint32_t handle)
{
	struct fd_bo *bo;

	bo = dev->funcs->bo_from_handle(dev, size, handle);
	if (!bo) {
		struct drm_gem_close req = {
				.handle = handle,
		};
		drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
		return NULL;
	}
	bo->dev = fd_device_ref(dev);
	bo->size = size;
	bo->handle = handle;
	atomic_set(&bo->refcnt, 1);
	list_inithead(&bo->list);
	/* add ourself into the handle table: */
	drmHashInsert(dev->handle_table, handle, bo);
	return bo;
}
Beispiel #9
0
/* set buffer name, and add to table, call w/ table_lock held: */
static void set_name(struct etna_bo *bo, uint32_t name)
{
	bo->name = name;
	/* add ourself into the handle table: */
	drmHashInsert(bo->dev->handle_table, name, bo);
}
Beispiel #10
0
int
getDRIDrawableInfoLocked(void *drawHash, Display *display, int screen, Drawable draw,
			 unsigned lockFlags, int drmFD, drm_context_t drmContext, 
			 drmAddress sarea, Bool updateInfo, drawableInfo **info, 
			 unsigned long infoSize)
{
  drawableInfo *drawInfo;
  void *res;
  drm_drawable_t drmDraw=0;
  volatile drm_sarea_t *pSarea = (drm_sarea_t *) sarea;
  drm_clip_rect_t *clipFront, *clipBack;

  int ret;


  if (drmHashLookup(drawHash, (unsigned long) draw, &res)) {

      /*
       * The drawable is unknown to us. Create it and put it in the
       * hash table.
       */

      DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); 
      if (!uniDRICreateDrawable(display, screen, draw,
				&drmDraw)) {
	DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); 
	  return 1;
      }
      DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); 


      drawInfo = (drawableInfo *) malloc(infoSize);
      if (!drawInfo) return 1;

      drawInfo->drmDraw = drmDraw;
      drawInfo->stamp = 0;
      drawInfo->clipFront = 0;
      drawInfo->clipBack = 0;

      drmHashInsert( drawHash, (unsigned long) draw, drawInfo);

  } else {
      drawInfo = res;
  }


  drawInfo->touched = FALSE;
  while (!drawInfo->clipFront || drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) {

      /*
       * The drawable has been touched since we last got info about it.
       * obtain new info from the X server.
       */

      drawInfo->touched = TRUE;

      if (updateInfo || !drawInfo->clipFront) {
	  DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); 

	  ret = uniDRIGetDrawableInfo(display, screen, draw,
				      &drawInfo->index, &drawInfo->stamp, &drawInfo->x, 
				      &drawInfo->y, &drawInfo->w, &drawInfo->h,
				      &drawInfo->numClipFront, &clipFront, 
				      &drawInfo->backX, &drawInfo->backY,
				      &drawInfo->numClipBack, &clipBack);
	  
	  DRM_LIGHT_LOCK(drmFD, &pSarea->lock, drmContext); 

	  /*
	   * Error. Probably the drawable is destroyed. Return error and old values.
	   */

	  if (!ret) {
	      free(drawInfo);
	      drawInfo = NULL;
	      drmHashDelete(drawHash, (unsigned long) draw);
	      
	      DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
	      uniDRIDestroyDrawable( display, screen, draw);
	      DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);

	      return 1;
	  }
	  
	  if (drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) {

	      /*
	       * The info is already outdated. Sigh. Have another go.
	       */

	      XFree(clipFront);
	      XFree(clipBack);
	      continue;
	  }

	  if (drawInfo->clipFront) XFree(drawInfo->clipFront);
	  drawInfo->clipFront = clipFront;
	  if (drawInfo->clipBack) XFree(drawInfo->clipBack);
	  drawInfo->clipBack = clipBack;
      } else {
	  if (!drawInfo->clipFront) drawInfo->clipFront = (drm_clip_rect_t *) ~0UL;
	  drawInfo->stamp = drawStamp(pSarea, drawInfo->index);
      }
  }
  *info = drawInfo;
  return 0;
}
Beispiel #11
0
drm_public
int drm_tegra_bo_from_dmabuf(struct drm_tegra_bo **bop, struct drm_tegra *drm,
			     int fd, uint32_t flags)
{
	struct drm_tegra_bo *dup;
	struct drm_tegra_bo *bo;
	uint32_t handle;
	uint32_t size;
	int err;

	if (!drm || !bop)
		return -EINVAL;

	pthread_mutex_lock(&table_lock);

	bo = calloc(1, sizeof(*bo));
	if (!bo) {
		err = -ENOMEM;
		goto unlock;
	}

	err = drmPrimeFDToHandle(drm->fd, fd, &handle);
	if (err) {
		free(bo);
		bo = NULL;
		goto unlock;
	}

	/* check handle table to see if BO is already open */
	dup = lookup_bo(drm->handle_table, handle);
	if (dup) {
		DBG_BO(dup, "success reused\n");
		free(bo);
		bo = dup;
		goto unlock;
	}

	errno = 0;
	/* lseek() to get bo size */
	size = lseek(fd, 0, SEEK_END);
	lseek(fd, 0, SEEK_CUR);
	/* store lseek() error number */
	err = -errno;

	atomic_set(&bo->ref, 1);
	bo->handle = handle;
	bo->flags = flags;
	bo->size = size;
	bo->drm = drm;

	VG_BO_ALLOC(bo);

	/* add ourself into the handle table: */
	drmHashInsert(drm->handle_table, handle, bo);

	/* handle lseek() error */
	if (err) {
		VDBG_BO(bo, "lseek failed %d (%s)\n", err, strerror(-err));
		drm_tegra_bo_free(bo);
		bo = NULL;
	} else {
		DBG_BO(bo, "success\n");
	}

unlock:
	pthread_mutex_unlock(&table_lock);

	*bop = bo;

	return err;
}
Beispiel #12
0
drm_public
int drm_tegra_bo_from_name(struct drm_tegra_bo **bop, struct drm_tegra *drm,
			   uint32_t name, uint32_t flags)
{
	struct drm_gem_open args;
	struct drm_tegra_bo *dup;
	struct drm_tegra_bo *bo;
	int err = 0;

	if (!drm || !name || !bop)
		return -EINVAL;

	pthread_mutex_lock(&table_lock);

	/* check name table first, to see if BO is already open */
	bo = lookup_bo(drm->name_table, name);
	if (bo)
		goto unlock;

	bo = calloc(1, sizeof(*bo));
	if (!bo) {
		err = -ENOMEM;
		goto unlock;
	}

	memset(&args, 0, sizeof(args));
	args.name = name;

	err = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, &args);
	if (err < 0) {
		VDBG_DRM(drm, "failed name 0x%08X err %d strerror(%s)\n",
			 name, err, strerror(-err));
		err = -errno;
		free(bo);
		bo = NULL;
		goto unlock;
	}

	/* check handle table second, to see if BO is already open */
	dup = lookup_bo(drm->handle_table, args.handle);
	if (dup) {
		VDBG_BO(dup, "success reused name 0x%08X\n", name);
		free(bo);
		bo = dup;
		goto unlock;
	}

	drmHashInsert(drm->name_table, name, bo);
	atomic_set(&bo->ref, 1);
	bo->name = name;
	bo->handle = args.handle;
	bo->flags = flags;
	bo->size = args.size;
	bo->drm = drm;

	DBG_BO(bo, "success\n");

	VG_BO_ALLOC(bo);

unlock:
	pthread_mutex_unlock(&table_lock);

	*bop = bo;

	return err;
}
Beispiel #13
0
drm_public int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
		     uint32_t flags, uint32_t size)
{
	struct drm_tegra_gem_create args;
	struct drm_tegra_bo *bo;
	int err;

	if (!drm || size == 0 || !bop)
		return -EINVAL;

	pthread_mutex_lock(&table_lock);
	bo = drm_tegra_bo_cache_alloc(drm, &size, flags);
	pthread_mutex_unlock(&table_lock);

	if (bo) {
		DBG_BO(bo, "success from cache\n");
		goto out;
	}

	bo = calloc(1, sizeof(*bo));
	if (!bo)
		return -ENOMEM;

	DRMINITLISTHEAD(&bo->push_list);
	DRMINITLISTHEAD(&bo->bo_list);
	atomic_set(&bo->ref, 1);
	bo->reuse = true;
	bo->flags = flags;
	bo->size = size;
	bo->drm = drm;

	memset(&args, 0, sizeof(args));
	args.flags = flags;
	args.size = size;

#ifndef NDEBUG
	if (drm->debug_bo_front_guard) {
		bo->offset += 4096;
		args.size += 4096;
	}

	if (drm->debug_bo_back_guard)
		args.size += 4096;
#endif
	err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, &args,
				  sizeof(args));
	if (err < 0) {
		VDBG_DRM(drm, "failed size %u bytes flags 0x%08X err %d (%s)\n",
			 size, flags, err, strerror(-err));
		free(bo);
		return err;
	}

	bo->handle = args.handle;

	DBG_BO(bo, "success new\n");
	VG_BO_ALLOC(bo);

#ifndef NDEBUG
	if (drm->debug_bo) {
		bo->debug_size = align(bo->size, 4096);
		drm->debug_bos_total_size += bo->debug_size;
		drm->debug_bos_allocated++;
	}
#endif
	drm_tegra_bo_setup_guards(bo);
	DBG_BO_STATS(drm);

	pthread_mutex_lock(&table_lock);
	/* add ourselves into the handle table */
	drmHashInsert(drm->handle_table, args.handle, bo);
	pthread_mutex_unlock(&table_lock);
out:
	*bop = bo;

	return 0;
}
Beispiel #14
0
int main(void)
{
    HashTablePtr  table;
    unsigned long i;
    int           ret = 0;

    printf("\n***** 256 consecutive integers ****\n");
    table = drmHashCreate();
    for (i = 0; i < 256; i++)
        drmHashInsert(table, i, (void *)(i << 16 | i));
    for (i = 0; i < 256; i++)
        ret |= check_table(table, i, (void *)(i << 16 | i));
    compute_dist(table);
    drmHashDestroy(table);

    printf("\n***** 1024 consecutive integers ****\n");
    table = drmHashCreate();
    for (i = 0; i < 1024; i++)
        drmHashInsert(table, i, (void *)(i << 16 | i));
    for (i = 0; i < 1024; i++)
        ret |= check_table(table, i, (void *)(i << 16 | i));
    compute_dist(table);
    drmHashDestroy(table);

    printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
    table = drmHashCreate();
    for (i = 0; i < 1024; i++)
        drmHashInsert(table, i*4096, (void *)(i << 16 | i));
    for (i = 0; i < 1024; i++)
        ret |= check_table(table, i*4096, (void *)(i << 16 | i));
    compute_dist(table);
    drmHashDestroy(table);

    printf("\n***** 1024 random integers ****\n");
    table = drmHashCreate();
    srandom(0xbeefbeef);
    for (i = 0; i < 1024; i++)
        drmHashInsert(table, random(), (void *)(i << 16 | i));
    srandom(0xbeefbeef);
    for (i = 0; i < 1024; i++)
        ret |= check_table(table, random(), (void *)(i << 16 | i));
    srandom(0xbeefbeef);
    for (i = 0; i < 1024; i++)
        ret |= check_table(table, random(), (void *)(i << 16 | i));
    compute_dist(table);
    drmHashDestroy(table);

    printf("\n***** 5000 random integers ****\n");
    table = drmHashCreate();
    srandom(0xbeefbeef);
    for (i = 0; i < 5000; i++)
        drmHashInsert(table, random(), (void *)(i << 16 | i));
    srandom(0xbeefbeef);
    for (i = 0; i < 5000; i++)
        ret |= check_table(table, random(), (void *)(i << 16 | i));
    srandom(0xbeefbeef);
    for (i = 0; i < 5000; i++)
        ret |= check_table(table, random(), (void *)(i << 16 | i));
    compute_dist(table);
    drmHashDestroy(table);

    return ret;
}