1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2012 VMware, Inc. All rights reserved.
8 #include <linux/slab.h>
9 #include "vmci_handle_array.h"
11 static size_t handle_arr_calc_size(u32 capacity
)
13 return VMCI_HANDLE_ARRAY_HEADER_SIZE
+
14 capacity
* sizeof(struct vmci_handle
);
17 struct vmci_handle_arr
*vmci_handle_arr_create(u32 capacity
, u32 max_capacity
)
19 struct vmci_handle_arr
*array
;
21 if (max_capacity
== 0 || capacity
> max_capacity
)
25 capacity
= min((u32
)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY
,
28 array
= kmalloc(handle_arr_calc_size(capacity
), GFP_ATOMIC
);
32 array
->capacity
= capacity
;
33 array
->max_capacity
= max_capacity
;
39 void vmci_handle_arr_destroy(struct vmci_handle_arr
*array
)
44 int vmci_handle_arr_append_entry(struct vmci_handle_arr
**array_ptr
,
45 struct vmci_handle handle
)
47 struct vmci_handle_arr
*array
= *array_ptr
;
49 if (unlikely(array
->size
>= array
->capacity
)) {
51 struct vmci_handle_arr
*new_array
;
52 u32 capacity_bump
= min(array
->max_capacity
- array
->capacity
,
54 size_t new_size
= handle_arr_calc_size(array
->capacity
+
57 if (array
->size
>= array
->max_capacity
)
58 return VMCI_ERROR_NO_MEM
;
60 new_array
= krealloc(array
, new_size
, GFP_ATOMIC
);
62 return VMCI_ERROR_NO_MEM
;
64 new_array
->capacity
+= capacity_bump
;
65 *array_ptr
= array
= new_array
;
68 array
->entries
[array
->size
] = handle
;
75 * Handle that was removed, VMCI_INVALID_HANDLE if entry not found.
77 struct vmci_handle
vmci_handle_arr_remove_entry(struct vmci_handle_arr
*array
,
78 struct vmci_handle entry_handle
)
80 struct vmci_handle handle
= VMCI_INVALID_HANDLE
;
83 for (i
= 0; i
< array
->size
; i
++) {
84 if (vmci_handle_is_equal(array
->entries
[i
], entry_handle
)) {
85 handle
= array
->entries
[i
];
87 array
->entries
[i
] = array
->entries
[array
->size
];
88 array
->entries
[array
->size
] = VMCI_INVALID_HANDLE
;
97 * Handle that was removed, VMCI_INVALID_HANDLE if array was empty.
99 struct vmci_handle
vmci_handle_arr_remove_tail(struct vmci_handle_arr
*array
)
101 struct vmci_handle handle
= VMCI_INVALID_HANDLE
;
105 handle
= array
->entries
[array
->size
];
106 array
->entries
[array
->size
] = VMCI_INVALID_HANDLE
;
113 * Handle at given index, VMCI_INVALID_HANDLE if invalid index.
116 vmci_handle_arr_get_entry(const struct vmci_handle_arr
*array
, u32 index
)
118 if (unlikely(index
>= array
->size
))
119 return VMCI_INVALID_HANDLE
;
121 return array
->entries
[index
];
124 bool vmci_handle_arr_has_entry(const struct vmci_handle_arr
*array
,
125 struct vmci_handle entry_handle
)
129 for (i
= 0; i
< array
->size
; i
++)
130 if (vmci_handle_is_equal(array
->entries
[i
], entry_handle
))
137 * NULL if the array is empty. Otherwise, a pointer to the array
138 * of VMCI handles in the handle array.
140 struct vmci_handle
*vmci_handle_arr_get_handles(struct vmci_handle_arr
*array
)
143 return array
->entries
;