/* lookup a buffer, call with table_lock mutex locked */ static struct drm_tegra_bo * lookup_bo(void *table, uint32_t key) { struct drm_tegra_bo_bucket *bucket; struct drm_tegra_bo *bo; void *value; if (drmHashLookup(table, key, &value)) return NULL; bo = value; if (!DRMLISTEMPTY(&bo->bo_list)) { /* mark BO as available for access under valgrind */ drm_tegra_reset_bo(bo, 0, false); /* take out BO from the bucket */ DRMLISTDELINIT(&bo->bo_list); /* update bucket stats */ bucket = drm_tegra_get_bucket(bo->drm, bo->size); bucket->num_entries--; } /* found, increment reference count */ atomic_inc(&bo->ref); return bo; }
static int check_table(HashTablePtr table, unsigned long key, void * value) { void *retval; int retcode = drmHashLookup(table, key, &retval); switch (retcode) { case -1: printf("Bad magic = 0x%08lx:" " key = %lu, expected = %p, returned = %p\n", table->magic, key, value, retval); break; case 1: printf("Not found: key = %lu, expected = %p, returned = %p\n", key, value, retval); break; case 0: if (value != retval) { printf("Bad value: key = %lu, expected = %p, returned = %p\n", key, value, retval); retcode = -1; } break; default: printf("Bad retcode = %d: key = %lu, expected = %p, returned = %p\n", retcode, key, value, retval); break; } return retcode; }
/* lookup a buffer, call w/ table_lock held: */ static struct fd_bo * lookup_bo(void *tbl, uint32_t key) { struct fd_bo *bo = NULL; if (!drmHashLookup(tbl, key, (void **)&bo)) { /* found, incr refcnt and return: */ bo = fd_bo_ref(bo); } return bo; }
/* lookup a buffer from it's handle, call w/ table_lock held: */ static struct etna_bo * lookup_bo(struct etna_device *dev, uint32_t handle) { struct etna_bo *bo = NULL; if (!drmHashLookup(dev->handle_table, handle, (void **)&bo)) { /* found, incr refcnt and return: */ bo = etna_bo_ref(bo); } return bo; }
/* lookup a buffer, call w/ table_lock held: */ static struct fd_bo * lookup_bo(void *tbl, uint32_t key) { struct fd_bo *bo = NULL; if (!drmHashLookup(tbl, key, (void **)&bo)) { /* found, incr refcnt and return: */ bo = fd_bo_ref(bo); /* don't break the bucket if this bo was found in one */ list_delinit(&bo->list); } return bo; }
void *hash_lookup_callback(struct locked_hash_table *table, unsigned long key, hash_callback_t func) { void *value; int ret; pthread_rwlock_rdlock(&table->lock); ret = drmHashLookup(table->table, key, &value); if (!ret && func) func(value); pthread_rwlock_unlock(&table->lock); return ret ? NULL : value; }
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; }
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; }
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; }