root/kern/lib/array.c

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

DEFINITIONS

This source file includes following definitions.
  1. array_create
  2. array_destroy
  3. array_init
  4. array_cleanup
  5. array_setsize
  6. array_remove

   1 /*-
   2  * Copyright (c) 2009 The NetBSD Foundation, Inc.
   3  * All rights reserved.
   4  *
   5  * This code is derived from software contributed to The NetBSD Foundation
   6  * by David A. Holland.
   7  *
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions
  10  * are met:
  11  * 1. Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  * 2. Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in the
  15  *    documentation and/or other materials provided with the distribution.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27  * POSSIBILITY OF SUCH DAMAGE.
  28  */
  29 
  30 #define ARRAYINLINE
  31 
  32 #include <types.h>
  33 #include <kern/errno.h>
  34 #include <lib.h>
  35 #include <array.h>
  36 
  37 struct array *
  38 array_create(void)
  39 {
  40         struct array *a;
  41 
  42         a = kmalloc(sizeof(*a));
  43         if (a != NULL) {
  44                 array_init(a);
  45         }
  46         return a;
  47 }
  48 
  49 void
  50 array_destroy(struct array *a)
  51 {
  52         array_cleanup(a);
  53         kfree(a);
  54 }
  55 
  56 void
  57 array_init(struct array *a)
  58 {
  59         a->num = a->max = 0;
  60         a->v = NULL;
  61 }
  62 
  63 void
  64 array_cleanup(struct array *a)
  65 {
  66         /*
  67          * Require array to be empty - helps avoid memory leaks since
  68          * we don't/can't free anything any contents may be pointing
  69          * to.
  70          */
  71         ARRAYASSERT(a->num == 0);
  72         kfree(a->v);
  73 #ifdef ARRAYS_CHECKED
  74         a->v = NULL;
  75 #endif
  76 }
  77 
  78 int
  79 array_setsize(struct array *a, unsigned num)
  80 {
  81         void **newptr;
  82         unsigned newmax;
  83 
  84         if (num > a->max) {
  85                 /* Don't touch A until the allocation succeeds. */
  86                 newmax = a->max;
  87                 while (num > newmax) {
  88                         newmax = newmax ? newmax*2 : 4;
  89                 }
  90 
  91                 /*
  92                  * We don't have krealloc, and it wouldn't be
  93                  * worthwhile to implement just for this. So just
  94                  * allocate a new block and copy. (Exercise: what
  95                  * about this and/or kmalloc makes it not worthwhile?)
  96                  */
  97 
  98                 newptr = kmalloc(newmax*sizeof(*a->v));
  99                 if (newptr == NULL) {
 100                         return ENOMEM;
 101                 }
 102                 memcpy(newptr, a->v, a->num*sizeof(*a->v));
 103                 kfree(a->v);
 104                 a->v = newptr;
 105                 a->max = newmax;
 106         }
 107         a->num = num;
 108 
 109         return 0;
 110 }
 111 
 112 void
 113 array_remove(struct array *a, unsigned index)
 114 {
 115         unsigned num_to_move;
 116 
 117         ARRAYASSERT(a->num <= a->max);
 118         ARRAYASSERT(index < a->num);
 119 
 120         num_to_move = a->num - (index + 1);
 121         memmove(a->v + index, a->v + index+1, num_to_move*sizeof(void *));
 122         a->num--;
 123 }

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