static void drmBOFreeList(drmBOList * list) { drmBONode *node; drmMMListHead *l; l = list->list.next; while (l != &list->list) { DRMLISTDEL(l); node = DRMLISTENTRY(drmBONode, l, head); free(node); l = list->list.next; list->numCurrent--; list->numOnList--; } l = list->free.next; while (l != &list->free) { DRMLISTDEL(l); node = DRMLISTENTRY(drmBONode, l, head); free(node); l = list->free.next; list->numCurrent--; } }
static int drmAdjustListNodes(drmBOList * list) { drmBONode *node; drmMMListHead *l; int ret = 0; while (list->numCurrent < list->numTarget) { node = (drmBONode *) malloc(sizeof(*node)); if (!node) { ret = -ENOMEM; break; } list->numCurrent++; DRMLISTADD(&node->head, &list->free); } while (list->numCurrent > list->numTarget) { l = list->free.next; if (l == &list->free) break; DRMLISTDEL(l); node = DRMLISTENTRY(drmBONode, l, head); free(node); list->numCurrent--; } return ret; }
static drmBONode * psbAddListItem(drmBOList * list, drmBO * item, uint64_t arg0, uint64_t arg1) { drmBONode *node; drmMMListHead *l; l = list->free.next; if (l == &list->free) { node = (drmBONode *) malloc(sizeof(*node)); if (!node) { return NULL; } list->numCurrent++; } else { DRMLISTDEL(l); node = DRMLISTENTRY(drmBONode, l, head); } memset(&node->bo_arg, 0, sizeof(node->bo_arg)); node->buf = item; node->arg0 = arg0; node->arg1 = arg1; DRMLISTADDTAIL(&node->head, &list->list); list->numOnList++; return node; }
static void drm_tegra_bo_free(struct drm_tegra_bo *bo) { struct drm_tegra *drm = bo->drm; struct drm_gem_close args; DRMLISTDEL(&bo->list); if (bo->map) munmap(bo->map, bo->size); memset(&args, 0, sizeof(args)); args.handle = bo->handle; drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &args); free(bo); }
/* Frees older cached buffers. Called under table_lock */ drm_private void drm_tegra_bo_cache_cleanup(struct drm_tegra *drm, time_t time) { struct drm_tegra_bo_cache *cache = &drm->bo_cache; time_t delta; int i; if (cache->time == time) return; for (i = 0; i < cache->num_buckets; i++) { struct drm_tegra_bo_bucket *bucket = &cache->cache_bucket[i]; struct drm_tegra_bo *bo; if (time && !bucket_free_up(drm, bucket, false)) continue; while (!DRMLISTEMPTY(&bucket->list)) { bo = DRMLISTENTRY(struct drm_tegra_bo, bucket->list.next, bo_list); delta = time - bo->free_time; /* keep things in cache for at least 1 second: */ if (time && delta <= 1) break; /* keep things in cache longer if not much */ if (time && delta < 60 && bucket->num_entries < 5) break; VG_BO_OBTAIN(bo); DRMLISTDEL(&bo->bo_list); drm_tegra_bo_free(bo); #ifndef NDEBUG if (drm->debug_bo) drm->debug_bos_cached--; #endif bucket->num_entries--; } } cache->time = time; }
static int drmBOResetList(drmBOList * list) { drmMMListHead *l; int ret; ret = drmAdjustListNodes(list); if (ret) return ret; l = list->list.next; while (l != &list->list) { DRMLISTDEL(l); DRMLISTADD(l, &list->free); list->numOnList--; l = list->list.next; } return drmAdjustListNodes(list); }