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 struct vmci_handle_arr
*vmci_handle_arr_create(u32 capacity
, u32 max_capacity
)
13 struct vmci_handle_arr
*array
;
15 if (max_capacity
== 0 || capacity
> max_capacity
)
19 capacity
= min((u32
)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY
,
22 array
= kmalloc(struct_size(array
, entries
, capacity
), GFP_ATOMIC
);
26 array
->capacity
= capacity
;
27 array
->max_capacity
= max_capacity
;
33 void vmci_handle_arr_destroy(struct vmci_handle_arr
*array
)
38 int vmci_handle_arr_append_entry(struct vmci_handle_arr
**array_ptr
,
39 struct vmci_handle handle
)
41 struct vmci_handle_arr
*array
= *array_ptr
;
43 if (unlikely(array
->size
>= array
->capacity
)) {
45 struct vmci_handle_arr
*new_array
;
46 u32 capacity_bump
= min(array
->max_capacity
- array
->capacity
,
48 size_t new_size
= struct_size(array
, entries
,
49 size_add(array
->capacity
, capacity_bump
));
51 if (array
->size
>= array
->max_capacity
)
52 return VMCI_ERROR_NO_MEM
;
54 new_array
= krealloc(array
, new_size
, GFP_ATOMIC
);
56 return VMCI_ERROR_NO_MEM
;
58 new_array
->capacity
+= capacity_bump
;
59 *array_ptr
= array
= new_array
;
62 array
->entries
[array
->size
] = handle
;
69 * Handle that was removed, VMCI_INVALID_HANDLE if entry not found.
71 struct vmci_handle
vmci_handle_arr_remove_entry(struct vmci_handle_arr
*array
,
72 struct vmci_handle entry_handle
)
74 struct vmci_handle handle
= VMCI_INVALID_HANDLE
;
77 for (i
= 0; i
< array
->size
; i
++) {
78 if (vmci_handle_is_equal(array
->entries
[i
], entry_handle
)) {
79 handle
= array
->entries
[i
];
81 array
->entries
[i
] = array
->entries
[array
->size
];
82 array
->entries
[array
->size
] = VMCI_INVALID_HANDLE
;
91 * Handle that was removed, VMCI_INVALID_HANDLE if array was empty.
93 struct vmci_handle
vmci_handle_arr_remove_tail(struct vmci_handle_arr
*array
)
95 struct vmci_handle handle
= VMCI_INVALID_HANDLE
;
99 handle
= array
->entries
[array
->size
];
100 array
->entries
[array
->size
] = VMCI_INVALID_HANDLE
;
107 * Handle at given index, VMCI_INVALID_HANDLE if invalid index.
110 vmci_handle_arr_get_entry(const struct vmci_handle_arr
*array
, u32 index
)
112 if (unlikely(index
>= array
->size
))
113 return VMCI_INVALID_HANDLE
;
115 return array
->entries
[index
];
118 bool vmci_handle_arr_has_entry(const struct vmci_handle_arr
*array
,
119 struct vmci_handle entry_handle
)
123 for (i
= 0; i
< array
->size
; i
++)
124 if (vmci_handle_is_equal(array
->entries
[i
], entry_handle
))
131 * NULL if the array is empty. Otherwise, a pointer to the array
132 * of VMCI handles in the handle array.
134 struct vmci_handle
*vmci_handle_arr_get_handles(struct vmci_handle_arr
*array
)
137 return array
->entries
;