root/drivers/gpu/drm/amd/display/dc/basics/vector.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dal_vector_construct
  2. dal_vector_presized_costruct
  3. dal_vector_presized_create
  4. dal_vector_create
  5. dal_vector_destruct
  6. dal_vector_destroy
  7. dal_vector_get_count
  8. dal_vector_at_index
  9. dal_vector_remove_at_index
  10. dal_vector_set_at_index
  11. calc_increased_capacity
  12. dal_vector_insert_at
  13. dal_vector_append
  14. dal_vector_clone
  15. dal_vector_capacity
  16. dal_vector_reserve
  17. dal_vector_clear

   1 /*
   2  * Copyright 2012-15 Advanced Micro Devices, Inc.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors: AMD
  23  *
  24  */
  25 
  26 #include <linux/slab.h>
  27 
  28 #include "dm_services.h"
  29 #include "include/vector.h"
  30 
  31 bool dal_vector_construct(
  32         struct vector *vector,
  33         struct dc_context *ctx,
  34         uint32_t capacity,
  35         uint32_t struct_size)
  36 {
  37         vector->container = NULL;
  38 
  39         if (!struct_size || !capacity) {
  40                 /* Container must be non-zero size*/
  41                 BREAK_TO_DEBUGGER();
  42                 return false;
  43         }
  44 
  45         vector->container = kcalloc(capacity, struct_size, GFP_KERNEL);
  46         if (vector->container == NULL)
  47                 return false;
  48         vector->capacity = capacity;
  49         vector->struct_size = struct_size;
  50         vector->count = 0;
  51         vector->ctx = ctx;
  52         return true;
  53 }
  54 
  55 bool dal_vector_presized_costruct(
  56         struct vector *vector,
  57         struct dc_context *ctx,
  58         uint32_t count,
  59         void *initial_value,
  60         uint32_t struct_size)
  61 {
  62         uint32_t i;
  63 
  64         vector->container = NULL;
  65 
  66         if (!struct_size || !count) {
  67                 /* Container must be non-zero size*/
  68                 BREAK_TO_DEBUGGER();
  69                 return false;
  70         }
  71 
  72         vector->container = kcalloc(count, struct_size, GFP_KERNEL);
  73 
  74         if (vector->container == NULL)
  75                 return false;
  76 
  77         /* If caller didn't supply initial value then the default
  78          * of all zeros is expected, which is exactly what dal_alloc()
  79          * initialises the memory to. */
  80         if (NULL != initial_value) {
  81                 for (i = 0; i < count; ++i)
  82                         memmove(
  83                                 vector->container + i * struct_size,
  84                                 initial_value,
  85                                 struct_size);
  86         }
  87 
  88         vector->capacity = count;
  89         vector->struct_size = struct_size;
  90         vector->count = count;
  91         return true;
  92 }
  93 
  94 struct vector *dal_vector_presized_create(
  95         struct dc_context *ctx,
  96         uint32_t size,
  97         void *initial_value,
  98         uint32_t struct_size)
  99 {
 100         struct vector *vector = kzalloc(sizeof(struct vector), GFP_KERNEL);
 101 
 102         if (vector == NULL)
 103                 return NULL;
 104 
 105         if (dal_vector_presized_costruct(
 106                 vector, ctx, size, initial_value, struct_size))
 107                 return vector;
 108 
 109         BREAK_TO_DEBUGGER();
 110         kfree(vector);
 111         return NULL;
 112 }
 113 
 114 struct vector *dal_vector_create(
 115         struct dc_context *ctx,
 116         uint32_t capacity,
 117         uint32_t struct_size)
 118 {
 119         struct vector *vector = kzalloc(sizeof(struct vector), GFP_KERNEL);
 120 
 121         if (vector == NULL)
 122                 return NULL;
 123 
 124         if (dal_vector_construct(vector, ctx, capacity, struct_size))
 125                 return vector;
 126 
 127         BREAK_TO_DEBUGGER();
 128         kfree(vector);
 129         return NULL;
 130 }
 131 
 132 void dal_vector_destruct(
 133         struct vector *vector)
 134 {
 135         kfree(vector->container);
 136         vector->count = 0;
 137         vector->capacity = 0;
 138 }
 139 
 140 void dal_vector_destroy(
 141         struct vector **vector)
 142 {
 143         if (vector == NULL || *vector == NULL)
 144                 return;
 145         dal_vector_destruct(*vector);
 146         kfree(*vector);
 147         *vector = NULL;
 148 }
 149 
 150 uint32_t dal_vector_get_count(
 151         const struct vector *vector)
 152 {
 153         return vector->count;
 154 }
 155 
 156 void *dal_vector_at_index(
 157         const struct vector *vector,
 158         uint32_t index)
 159 {
 160         if (vector->container == NULL || index >= vector->count)
 161                 return NULL;
 162         return vector->container + (index * vector->struct_size);
 163 }
 164 
 165 bool dal_vector_remove_at_index(
 166         struct vector *vector,
 167         uint32_t index)
 168 {
 169         if (index >= vector->count)
 170                 return false;
 171 
 172         if (index != vector->count - 1)
 173                 memmove(
 174                         vector->container + (index * vector->struct_size),
 175                         vector->container + ((index + 1) * vector->struct_size),
 176                         (vector->count - index - 1) * vector->struct_size);
 177         vector->count -= 1;
 178 
 179         return true;
 180 }
 181 
 182 void dal_vector_set_at_index(
 183         const struct vector *vector,
 184         const void *what,
 185         uint32_t index)
 186 {
 187         void *where = dal_vector_at_index(vector, index);
 188 
 189         if (!where) {
 190                 BREAK_TO_DEBUGGER();
 191                 return;
 192         }
 193         memmove(
 194                 where,
 195                 what,
 196                 vector->struct_size);
 197 }
 198 
 199 static inline uint32_t calc_increased_capacity(
 200         uint32_t old_capacity)
 201 {
 202         return old_capacity * 2;
 203 }
 204 
 205 bool dal_vector_insert_at(
 206         struct vector *vector,
 207         const void *what,
 208         uint32_t position)
 209 {
 210         uint8_t *insert_address;
 211 
 212         if (vector->count == vector->capacity) {
 213                 if (!dal_vector_reserve(
 214                         vector,
 215                         calc_increased_capacity(vector->capacity)))
 216                         return false;
 217         }
 218 
 219         insert_address = vector->container + (vector->struct_size * position);
 220 
 221         if (vector->count && position < vector->count)
 222                 memmove(
 223                         insert_address + vector->struct_size,
 224                         insert_address,
 225                         vector->struct_size * (vector->count - position));
 226 
 227         memmove(
 228                 insert_address,
 229                 what,
 230                 vector->struct_size);
 231 
 232         vector->count++;
 233 
 234         return true;
 235 }
 236 
 237 bool dal_vector_append(
 238         struct vector *vector,
 239         const void *item)
 240 {
 241         return dal_vector_insert_at(vector, item, vector->count);
 242 }
 243 
 244 struct vector *dal_vector_clone(
 245         const struct vector *vector)
 246 {
 247         struct vector *vec_cloned;
 248         uint32_t count;
 249 
 250         /* create new vector */
 251         count = dal_vector_get_count(vector);
 252 
 253         if (count == 0)
 254                 /* when count is 0 we still want to create clone of the vector
 255                  */
 256                 vec_cloned = dal_vector_create(
 257                         vector->ctx,
 258                         vector->capacity,
 259                         vector->struct_size);
 260         else
 261                 /* Call "presized create" version, independently of how the
 262                  * original vector was created.
 263                  * The owner of original vector must know how to treat the new
 264                  * vector - as "presized" or as "regular".
 265                  * But from vector point of view it doesn't matter. */
 266                 vec_cloned = dal_vector_presized_create(vector->ctx, count,
 267                         NULL,/* no initial value */
 268                         vector->struct_size);
 269 
 270         if (NULL == vec_cloned) {
 271                 BREAK_TO_DEBUGGER();
 272                 return NULL;
 273         }
 274 
 275         /* copy vector's data */
 276         memmove(vec_cloned->container, vector->container,
 277                         vec_cloned->struct_size * vec_cloned->capacity);
 278 
 279         return vec_cloned;
 280 }
 281 
 282 uint32_t dal_vector_capacity(const struct vector *vector)
 283 {
 284         return vector->capacity;
 285 }
 286 
 287 bool dal_vector_reserve(struct vector *vector, uint32_t capacity)
 288 {
 289         void *new_container;
 290 
 291         if (capacity <= vector->capacity)
 292                 return true;
 293 
 294         new_container = krealloc(vector->container,
 295                                  capacity * vector->struct_size, GFP_KERNEL);
 296 
 297         if (new_container) {
 298                 vector->container = new_container;
 299                 vector->capacity = capacity;
 300                 return true;
 301         }
 302 
 303         return false;
 304 }
 305 
 306 void dal_vector_clear(struct vector *vector)
 307 {
 308         vector->count = 0;
 309 }

/* [<][>][^][v][top][bottom][index][help] */