4 * Copyright (C) 2012 VMware, Inc. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation version 2 and no later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include <linux/slab.h>
17 #include "vmci_handle_array.h"
19 static size_t handle_arr_calc_size(size_t capacity
)
21 return sizeof(struct vmci_handle_arr
) +
22 capacity
* sizeof(struct vmci_handle
);
25 struct vmci_handle_arr
*vmci_handle_arr_create(size_t capacity
)
27 struct vmci_handle_arr
*array
;
30 capacity
= VMCI_HANDLE_ARRAY_DEFAULT_SIZE
;
32 array
= kmalloc(handle_arr_calc_size(capacity
), GFP_ATOMIC
);
36 array
->capacity
= capacity
;
42 void vmci_handle_arr_destroy(struct vmci_handle_arr
*array
)
47 void vmci_handle_arr_append_entry(struct vmci_handle_arr
**array_ptr
,
48 struct vmci_handle handle
)
50 struct vmci_handle_arr
*array
= *array_ptr
;
52 if (unlikely(array
->size
>= array
->capacity
)) {
54 struct vmci_handle_arr
*new_array
;
55 size_t new_capacity
= array
->capacity
* VMCI_ARR_CAP_MULT
;
56 size_t new_size
= handle_arr_calc_size(new_capacity
);
58 new_array
= krealloc(array
, new_size
, GFP_ATOMIC
);
62 new_array
->capacity
= new_capacity
;
63 *array_ptr
= array
= new_array
;
66 array
->entries
[array
->size
] = handle
;
71 * Handle that was removed, VMCI_INVALID_HANDLE if entry not found.
73 struct vmci_handle
vmci_handle_arr_remove_entry(struct vmci_handle_arr
*array
,
74 struct vmci_handle entry_handle
)
76 struct vmci_handle handle
= VMCI_INVALID_HANDLE
;
79 for (i
= 0; i
< array
->size
; i
++) {
80 if (vmci_handle_is_equal(array
->entries
[i
], entry_handle
)) {
81 handle
= array
->entries
[i
];
83 array
->entries
[i
] = array
->entries
[array
->size
];
84 array
->entries
[array
->size
] = VMCI_INVALID_HANDLE
;
93 * Handle that was removed, VMCI_INVALID_HANDLE if array was empty.
95 struct vmci_handle
vmci_handle_arr_remove_tail(struct vmci_handle_arr
*array
)
97 struct vmci_handle handle
= VMCI_INVALID_HANDLE
;
101 handle
= array
->entries
[array
->size
];
102 array
->entries
[array
->size
] = VMCI_INVALID_HANDLE
;
109 * Handle at given index, VMCI_INVALID_HANDLE if invalid index.
112 vmci_handle_arr_get_entry(const struct vmci_handle_arr
*array
, size_t index
)
114 if (unlikely(index
>= array
->size
))
115 return VMCI_INVALID_HANDLE
;
117 return array
->entries
[index
];
120 bool vmci_handle_arr_has_entry(const struct vmci_handle_arr
*array
,
121 struct vmci_handle entry_handle
)
125 for (i
= 0; i
< array
->size
; i
++)
126 if (vmci_handle_is_equal(array
->entries
[i
], entry_handle
))
133 * NULL if the array is empty. Otherwise, a pointer to the array
134 * of VMCI handles in the handle array.
136 struct vmci_handle
*vmci_handle_arr_get_handles(struct vmci_handle_arr
*array
)
139 return array
->entries
;