mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/optimize_BLE_memory_debug' into 'master'
component/bt: optimize bluetooth memory debug See merge request idf/esp-idf!3047
This commit is contained in:
commit
60a9462f6e
@ -1,38 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "hci/buffer_allocator.h"
|
||||
#include "osi/allocator.h"
|
||||
|
||||
// TODO(zachoverflow): move the assertion into osi_malloc in the future
|
||||
static void *buffer_alloc(size_t size)
|
||||
{
|
||||
return osi_malloc(size);
|
||||
}
|
||||
static void buffer_free(void *p)
|
||||
{
|
||||
osi_free(p);
|
||||
}
|
||||
static const allocator_t interface = {
|
||||
buffer_alloc,
|
||||
buffer_free
|
||||
};
|
||||
|
||||
const allocator_t *buffer_allocator_get_interface()
|
||||
{
|
||||
return &interface;
|
||||
}
|
@ -19,7 +19,6 @@
|
||||
#include "common/bt_defs.h"
|
||||
#include "common/bt_trace.h"
|
||||
#include "stack/bt_types.h"
|
||||
#include "hci/buffer_allocator.h"
|
||||
#include "osi/fixed_queue.h"
|
||||
#include "hci/hci_hal.h"
|
||||
#include "hci/hci_internals.h"
|
||||
@ -54,7 +53,6 @@ static const uint16_t outbound_event_types[] = {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const allocator_t *allocator;
|
||||
size_t buffer_size;
|
||||
fixed_queue_t *rx_q;
|
||||
} hci_hal_env_t;
|
||||
@ -82,7 +80,6 @@ static void hci_hal_env_init(
|
||||
assert(buffer_size > 0);
|
||||
assert(max_buffer_count > 0);
|
||||
|
||||
hci_hal_env.allocator = buffer_allocator_get_interface();
|
||||
hci_hal_env.buffer_size = buffer_size;
|
||||
|
||||
hci_hal_env.rx_q = fixed_queue_new(max_buffer_count);
|
||||
@ -97,7 +94,7 @@ static void hci_hal_env_init(
|
||||
|
||||
static void hci_hal_env_deinit(void)
|
||||
{
|
||||
fixed_queue_free(hci_hal_env.rx_q, hci_hal_env.allocator->free);
|
||||
fixed_queue_free(hci_hal_env.rx_q, osi_free_func);
|
||||
hci_hal_env.rx_q = NULL;
|
||||
}
|
||||
|
||||
@ -254,21 +251,21 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
|
||||
STREAM_TO_UINT8(len, stream);
|
||||
HCI_TRACE_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n",
|
||||
packet->len, len);
|
||||
hci_hal_env.allocator->free(packet);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
|
||||
HCI_TRACE_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x,"
|
||||
" min %x, max %x\n", __func__, type,
|
||||
DATA_TYPE_ACL, DATA_TYPE_EVENT);
|
||||
hci_hal_env.allocator->free(packet);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
hdr_size = preamble_sizes[type - 1];
|
||||
if (packet->len < hdr_size) {
|
||||
HCI_TRACE_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d",
|
||||
type, packet->len, hdr_size);
|
||||
hci_hal_env.allocator->free(packet);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
if (type == DATA_TYPE_ACL) {
|
||||
@ -282,13 +279,13 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
|
||||
if ((length + hdr_size) != packet->len) {
|
||||
HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
|
||||
"pkt_len=%d", type, hdr_size, length, packet->len);
|
||||
hci_hal_env.allocator->free(packet);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
#if SCAN_QUEUE_CONGEST_CHECK
|
||||
if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) {
|
||||
HCI_TRACE_ERROR("BtuQueue is congested");
|
||||
hci_hal_env.allocator->free(packet);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -324,7 +321,8 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
|
||||
}
|
||||
|
||||
pkt_size = BT_HDR_SIZE + len;
|
||||
pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size);
|
||||
pkt = (BT_HDR *) osi_calloc(pkt_size);
|
||||
//pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size);
|
||||
if (!pkt) {
|
||||
HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
|
||||
return -1;
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "hci/hci_layer.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "hci/packet_fragmenter.h"
|
||||
#include "hci/buffer_allocator.h"
|
||||
#include "osi/list.h"
|
||||
#include "osi/alarm.h"
|
||||
#include "osi/thread.h"
|
||||
@ -78,7 +77,6 @@ static xQueueHandle xHciHostQueue;
|
||||
static bool hci_host_startup_flag;
|
||||
|
||||
// Modules we import and callbacks we export
|
||||
static const allocator_t *buffer_allocator;
|
||||
static const hci_hal_t *hal;
|
||||
static const hci_hal_callbacks_t hal_callbacks;
|
||||
static const packet_fragmenter_t *packet_fragmenter;
|
||||
@ -197,10 +195,10 @@ static void hci_layer_deinit_env(void)
|
||||
command_waiting_response_t *cmd_wait_q;
|
||||
|
||||
if (hci_host_env.command_queue) {
|
||||
fixed_queue_free(hci_host_env.command_queue, allocator_calloc.free);
|
||||
fixed_queue_free(hci_host_env.command_queue, osi_free_func);
|
||||
}
|
||||
if (hci_host_env.packet_queue) {
|
||||
fixed_queue_free(hci_host_env.packet_queue, buffer_allocator->free);
|
||||
fixed_queue_free(hci_host_env.packet_queue, osi_free_func);
|
||||
}
|
||||
|
||||
cmd_wait_q = &hci_host_env.cmd_waiting_q;
|
||||
@ -321,7 +319,7 @@ static void event_command_ready(fixed_queue_t *queue)
|
||||
|
||||
if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE){
|
||||
packet_fragmenter->fragment_and_dispatch(wait_entry->command);
|
||||
buffer_allocator->free(wait_entry->command);
|
||||
osi_free(wait_entry->command);
|
||||
osi_free(wait_entry);
|
||||
return;
|
||||
}
|
||||
@ -354,19 +352,19 @@ static void transmit_fragment(BT_HDR *packet, bool send_transmit_finished)
|
||||
hal->transmit_data(type, packet->data + packet->offset, packet->len);
|
||||
|
||||
if (event != MSG_STACK_TO_HC_HCI_CMD && send_transmit_finished) {
|
||||
buffer_allocator->free(packet);
|
||||
osi_free(packet);
|
||||
}
|
||||
}
|
||||
|
||||
static void fragmenter_transmit_finished(BT_HDR *packet, bool all_fragments_sent)
|
||||
{
|
||||
if (all_fragments_sent) {
|
||||
buffer_allocator->free(packet);
|
||||
osi_free(packet);
|
||||
} else {
|
||||
// This is kind of a weird case, since we're dispatching a partially sent packet
|
||||
// up to a higher layer.
|
||||
// TODO(zachoverflow): rework upper layer so this isn't necessary.
|
||||
//buffer_allocator->free(packet);
|
||||
//osi_free(packet);
|
||||
|
||||
/* dispatch_reassembled(packet) will send the packet back to the higher layer
|
||||
when controller buffer is not enough. hci will send the remain packet back
|
||||
@ -484,17 +482,17 @@ intercepted:
|
||||
// If it has a callback, it's responsible for freeing the packet
|
||||
if (event_code == HCI_COMMAND_STATUS_EVT ||
|
||||
(!wait_entry->complete_callback && !wait_entry->complete_future)) {
|
||||
buffer_allocator->free(packet);
|
||||
osi_free(packet);
|
||||
}
|
||||
|
||||
// If it has a callback, it's responsible for freeing the command
|
||||
if (event_code == HCI_COMMAND_COMPLETE_EVT || !wait_entry->status_callback) {
|
||||
buffer_allocator->free(wait_entry->command);
|
||||
osi_free(wait_entry->command);
|
||||
}
|
||||
|
||||
osi_free(wait_entry);
|
||||
} else {
|
||||
buffer_allocator->free(packet);
|
||||
osi_free(packet);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -506,7 +504,7 @@ static void dispatch_reassembled(BT_HDR *packet)
|
||||
// Events should already have been dispatched before this point
|
||||
//Tell Up-layer received packet.
|
||||
if (btu_task_post(SIG_BTU_HCI_MSG, packet, TASK_POST_BLOCKING) != TASK_POST_SUCCESS) {
|
||||
buffer_allocator->free(packet);
|
||||
osi_free(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,7 +571,6 @@ static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
|
||||
|
||||
const hci_t *hci_layer_get_interface()
|
||||
{
|
||||
buffer_allocator = buffer_allocator_get_interface();
|
||||
hal = hci_hal_h4_get_interface();
|
||||
packet_fragmenter = packet_fragmenter_get_interface();
|
||||
|
||||
|
@ -20,14 +20,12 @@
|
||||
|
||||
#include "osi/allocator.h"
|
||||
#include "stack/bt_types.h"
|
||||
#include "hci/buffer_allocator.h"
|
||||
#include "stack/hcidefs.h"
|
||||
#include "stack/hcimsgs.h"
|
||||
#include "hci/hci_internals.h"
|
||||
#include "hci/hci_layer.h"
|
||||
#include "hci/hci_packet_factory.h"
|
||||
|
||||
static const allocator_t *buffer_allocator;
|
||||
|
||||
static BT_HDR *make_packet(size_t data_size);
|
||||
static BT_HDR *make_command_no_params(uint16_t opcode);
|
||||
@ -228,7 +226,7 @@ static BT_HDR *make_command(uint16_t opcode, size_t parameter_size, uint8_t **st
|
||||
|
||||
static BT_HDR *make_packet(size_t data_size)
|
||||
{
|
||||
BT_HDR *ret = (BT_HDR *)buffer_allocator->alloc(sizeof(BT_HDR) + data_size);
|
||||
BT_HDR *ret = (BT_HDR *)osi_calloc(sizeof(BT_HDR) + data_size);
|
||||
assert(ret);
|
||||
ret->event = 0;
|
||||
ret->offset = 0;
|
||||
@ -264,6 +262,5 @@ static const hci_packet_factory_t interface = {
|
||||
|
||||
const hci_packet_factory_t *hci_packet_factory_get_interface()
|
||||
{
|
||||
buffer_allocator = buffer_allocator_get_interface();
|
||||
return &interface;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include "common/bt_defs.h"
|
||||
|
||||
#include "hci/buffer_allocator.h"
|
||||
#include "stack/bt_types.h"
|
||||
#include "stack/hcimsgs.h"
|
||||
#include "hci/hci_layer.h"
|
||||
@ -26,8 +25,6 @@
|
||||
|
||||
static const command_opcode_t NO_OPCODE_CHECKING = 0;
|
||||
|
||||
static const allocator_t *buffer_allocator;
|
||||
|
||||
static uint8_t *read_command_complete_header(
|
||||
BT_HDR *response,
|
||||
command_opcode_t expected_opcode,
|
||||
@ -37,7 +34,7 @@ static void parse_generic_command_complete(BT_HDR *response)
|
||||
{
|
||||
read_command_complete_header(response, NO_OPCODE_CHECKING, 0 /* bytes after */);
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_read_buffer_size_response(
|
||||
@ -54,7 +51,7 @@ static void parse_read_buffer_size_response(
|
||||
STREAM_TO_UINT8(*sco_data_size_ptr, stream);
|
||||
STREAM_TO_UINT16(*acl_buffer_count_ptr, stream);
|
||||
STREAM_TO_UINT16(*sco_buffer_count_ptr, stream);
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_read_local_version_info_response(
|
||||
@ -70,7 +67,7 @@ static void parse_read_local_version_info_response(
|
||||
STREAM_TO_UINT16(bt_version->manufacturer, stream);
|
||||
STREAM_TO_UINT16(bt_version->lmp_subversion, stream);
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_read_bd_addr_response(
|
||||
@ -82,7 +79,7 @@ static void parse_read_bd_addr_response(
|
||||
assert(stream != NULL);
|
||||
STREAM_TO_BDADDR(address_ptr->address, stream);
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_read_local_supported_commands_response(
|
||||
@ -95,7 +92,7 @@ static void parse_read_local_supported_commands_response(
|
||||
assert(stream != NULL);
|
||||
STREAM_TO_ARRAY(supported_commands_ptr, stream, (int)supported_commands_length);
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_read_local_extended_features_response(
|
||||
@ -118,7 +115,7 @@ static void parse_read_local_extended_features_response(
|
||||
"THIS MAY INDICATE A FIRMWARE/CONTROLLER ISSUE.", __func__);
|
||||
}
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_ble_read_white_list_size_response(
|
||||
@ -130,7 +127,7 @@ static void parse_ble_read_white_list_size_response(
|
||||
assert(stream != NULL);
|
||||
STREAM_TO_UINT8(*white_list_size_ptr, stream);
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_ble_read_buffer_size_response(
|
||||
@ -144,7 +141,7 @@ static void parse_ble_read_buffer_size_response(
|
||||
STREAM_TO_UINT16(*data_size_ptr, stream);
|
||||
STREAM_TO_UINT8(*acl_buffer_count_ptr, stream);
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_ble_read_supported_states_response(
|
||||
@ -157,7 +154,7 @@ static void parse_ble_read_supported_states_response(
|
||||
assert(stream != NULL);
|
||||
STREAM_TO_ARRAY(supported_states, stream, (int)supported_states_size);
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_ble_read_local_supported_features_response(
|
||||
@ -169,7 +166,7 @@ static void parse_ble_read_local_supported_features_response(
|
||||
assert(stream != NULL);
|
||||
STREAM_TO_ARRAY(supported_features->as_array, stream, (int)sizeof(bt_device_features_t));
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_ble_read_resolving_list_size_response(
|
||||
@ -180,7 +177,7 @@ static void parse_ble_read_resolving_list_size_response(
|
||||
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_RESOLVING_LIST_SIZE, 1 /* bytes after */);
|
||||
STREAM_TO_UINT8(*resolving_list_size_ptr, stream);
|
||||
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
static void parse_ble_read_suggested_default_data_length_response(
|
||||
@ -192,7 +189,7 @@ static void parse_ble_read_suggested_default_data_length_response(
|
||||
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */);
|
||||
STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream);
|
||||
STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream);
|
||||
buffer_allocator->free(response);
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
// Internal functions
|
||||
@ -255,7 +252,6 @@ static const hci_packet_parser_t interface = {
|
||||
|
||||
const hci_packet_parser_t *hci_packet_parser_get_interface()
|
||||
{
|
||||
buffer_allocator = buffer_allocator_get_interface();
|
||||
return &interface;
|
||||
}
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _BUFFER_ALLOCATOR_H_
|
||||
|
||||
#include "osi/allocator.h"
|
||||
|
||||
const allocator_t *buffer_allocator_get_interface();
|
||||
|
||||
#endif /*_BUFFER_ALLOCATOR_H_*/
|
@ -19,7 +19,6 @@
|
||||
#include "common/bt_trace.h"
|
||||
#include "common/bt_defs.h"
|
||||
#include "device/controller.h"
|
||||
#include "hci/buffer_allocator.h"
|
||||
#include "hci/hci_internals.h"
|
||||
#include "hci/hci_layer.h"
|
||||
#include "hci/packet_fragmenter.h"
|
||||
@ -44,7 +43,6 @@
|
||||
|
||||
// Our interface and callbacks
|
||||
static const packet_fragmenter_t interface;
|
||||
static const allocator_t *buffer_allocator;
|
||||
static const controller_t *controller;
|
||||
static const packet_fragmenter_callbacks_t *callbacks;
|
||||
static hash_map_t *partial_packets;
|
||||
@ -153,7 +151,7 @@ static void reassemble_and_dispatch(BT_HDR *packet)
|
||||
if (partial_packet) {
|
||||
HCI_TRACE_WARNING("%s found unfinished packet for handle with start packet. Dropping old.\n", __func__);
|
||||
hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
|
||||
buffer_allocator->free(partial_packet);
|
||||
osi_free(partial_packet);
|
||||
}
|
||||
|
||||
uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
|
||||
@ -165,8 +163,7 @@ static void reassemble_and_dispatch(BT_HDR *packet)
|
||||
callbacks->reassembled(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
partial_packet = (BT_HDR *)buffer_allocator->alloc(full_length + sizeof(BT_HDR));
|
||||
partial_packet = (BT_HDR *)osi_calloc(full_length + sizeof(BT_HDR));
|
||||
partial_packet->event = packet->event;
|
||||
partial_packet->len = full_length;
|
||||
partial_packet->offset = packet->len;
|
||||
@ -180,11 +177,11 @@ static void reassemble_and_dispatch(BT_HDR *packet)
|
||||
|
||||
hash_map_set(partial_packets, (void *)(uintptr_t)handle, partial_packet);
|
||||
// Free the old packet buffer, since we don't need it anymore
|
||||
buffer_allocator->free(packet);
|
||||
osi_free(packet);
|
||||
} else {
|
||||
if (!partial_packet) {
|
||||
HCI_TRACE_ERROR("%s got continuation for unknown packet. Dropping it.\n", __func__);
|
||||
buffer_allocator->free(packet);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -204,7 +201,7 @@ static void reassemble_and_dispatch(BT_HDR *packet)
|
||||
);
|
||||
|
||||
// Free the old packet buffer, since we don't need it anymore
|
||||
buffer_allocator->free(packet);
|
||||
osi_free(packet);
|
||||
partial_packet->offset = projected_offset;
|
||||
|
||||
if (partial_packet->offset == partial_packet->len) {
|
||||
@ -230,7 +227,6 @@ static const packet_fragmenter_t interface = {
|
||||
const packet_fragmenter_t *packet_fragmenter_get_interface()
|
||||
{
|
||||
controller = controller_get_interface();
|
||||
buffer_allocator = buffer_allocator_get_interface();
|
||||
return &interface;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ extern void vPortFree(void *pv);
|
||||
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
|
||||
#define OSI_MEM_DBG_INFO_MAX 1024
|
||||
#define OSI_MEM_DBG_INFO_MAX 1024*3
|
||||
typedef struct {
|
||||
void *p;
|
||||
int size;
|
||||
@ -175,13 +175,3 @@ void osi_free_func(void *ptr)
|
||||
#endif
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
const allocator_t allocator_malloc = {
|
||||
osi_malloc_func,
|
||||
osi_free_func
|
||||
};
|
||||
|
||||
const allocator_t allocator_calloc = {
|
||||
osi_calloc_func,
|
||||
osi_free_func
|
||||
};
|
||||
|
@ -35,12 +35,11 @@ typedef struct hash_map_t {
|
||||
hash_index_fn hash_fn;
|
||||
key_free_fn key_fn;
|
||||
data_free_fn data_fn;
|
||||
const allocator_t *allocator;
|
||||
key_equality_fn keys_are_equal;
|
||||
} hash_map_t;
|
||||
|
||||
// Hidden constructor for list, only to be used by us.
|
||||
list_t *list_new_internal(list_free_cb callback, const allocator_t *zeroed_allocator);
|
||||
list_t *list_new_internal(list_free_cb callback);
|
||||
|
||||
static void bucket_free_(void *data);
|
||||
static bool default_key_equality(const void *x, const void *y);
|
||||
@ -54,14 +53,11 @@ hash_map_t *hash_map_new_internal(
|
||||
hash_index_fn hash_fn,
|
||||
key_free_fn key_fn,
|
||||
data_free_fn data_fn,
|
||||
key_equality_fn equality_fn,
|
||||
const allocator_t *zeroed_allocator)
|
||||
key_equality_fn equality_fn)
|
||||
{
|
||||
assert(hash_fn != NULL);
|
||||
assert(num_bucket > 0);
|
||||
assert(zeroed_allocator != NULL);
|
||||
|
||||
hash_map_t *hash_map = zeroed_allocator->alloc(sizeof(hash_map_t));
|
||||
hash_map_t *hash_map = osi_calloc(sizeof(hash_map_t));
|
||||
if (hash_map == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -69,13 +65,12 @@ hash_map_t *hash_map_new_internal(
|
||||
hash_map->hash_fn = hash_fn;
|
||||
hash_map->key_fn = key_fn;
|
||||
hash_map->data_fn = data_fn;
|
||||
hash_map->allocator = zeroed_allocator;
|
||||
hash_map->keys_are_equal = equality_fn ? equality_fn : default_key_equality;
|
||||
|
||||
hash_map->num_bucket = num_bucket;
|
||||
hash_map->bucket = zeroed_allocator->alloc(sizeof(hash_map_bucket_t) * num_bucket);
|
||||
hash_map->bucket = osi_calloc(sizeof(hash_map_bucket_t) * num_bucket);
|
||||
if (hash_map->bucket == NULL) {
|
||||
zeroed_allocator->free(hash_map);
|
||||
osi_free(hash_map);
|
||||
return NULL;
|
||||
}
|
||||
return hash_map;
|
||||
@ -88,7 +83,7 @@ hash_map_t *hash_map_new(
|
||||
data_free_fn data_fn,
|
||||
key_equality_fn equality_fn)
|
||||
{
|
||||
return hash_map_new_internal(num_bucket, hash_fn, key_fn, data_fn, equality_fn, &allocator_calloc);
|
||||
return hash_map_new_internal(num_bucket, hash_fn, key_fn, data_fn, equality_fn);
|
||||
}
|
||||
|
||||
void hash_map_free(hash_map_t *hash_map)
|
||||
@ -97,8 +92,8 @@ void hash_map_free(hash_map_t *hash_map)
|
||||
return;
|
||||
}
|
||||
hash_map_clear(hash_map);
|
||||
hash_map->allocator->free(hash_map->bucket);
|
||||
hash_map->allocator->free(hash_map);
|
||||
osi_free(hash_map->bucket);
|
||||
osi_free(hash_map);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -137,7 +132,7 @@ bool hash_map_set(hash_map_t *hash_map, const void *key, void *data)
|
||||
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket;
|
||||
|
||||
if (hash_map->bucket[hash_key].list == NULL) {
|
||||
hash_map->bucket[hash_key].list = list_new_internal(bucket_free_, hash_map->allocator);
|
||||
hash_map->bucket[hash_key].list = list_new_internal(bucket_free_);
|
||||
if (hash_map->bucket[hash_key].list == NULL) {
|
||||
return false;
|
||||
}
|
||||
@ -153,7 +148,7 @@ bool hash_map_set(hash_map_t *hash_map, const void *key, void *data)
|
||||
} else {
|
||||
hash_map->hash_size++;
|
||||
}
|
||||
hash_map_entry = hash_map->allocator->alloc(sizeof(hash_map_entry_t));
|
||||
hash_map_entry = osi_calloc(sizeof(hash_map_entry_t));
|
||||
if (hash_map_entry == NULL) {
|
||||
return false;
|
||||
}
|
||||
@ -178,8 +173,13 @@ bool hash_map_erase(hash_map_t *hash_map, const void *key)
|
||||
}
|
||||
|
||||
hash_map->hash_size--;
|
||||
bool remove = list_remove(hash_bucket_list, hash_map_entry);
|
||||
if(list_is_empty(hash_map->bucket[hash_key].list)) {
|
||||
list_free(hash_map->bucket[hash_key].list);
|
||||
hash_map->bucket[hash_key].list = NULL;
|
||||
}
|
||||
|
||||
return list_remove(hash_bucket_list, hash_map_entry);
|
||||
return remove;
|
||||
}
|
||||
|
||||
void *hash_map_get(const hash_map_t *hash_map, const void *key)
|
||||
@ -242,7 +242,7 @@ static void bucket_free_(void *data)
|
||||
if (hash_map->data_fn) {
|
||||
hash_map->data_fn(hash_map_entry->data);
|
||||
}
|
||||
hash_map->allocator->free(hash_map_entry);
|
||||
osi_free(hash_map_entry);
|
||||
}
|
||||
|
||||
static hash_map_entry_t *find_bucket_entry_(list_t *hash_bucket_list,
|
||||
|
@ -24,18 +24,6 @@
|
||||
#include "esp_heap_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
typedef void *(*alloc_fn)(size_t size);
|
||||
typedef void (*free_fn)(void *ptr);
|
||||
|
||||
typedef struct {
|
||||
alloc_fn alloc;
|
||||
free_fn free;
|
||||
} allocator_t;
|
||||
|
||||
// allocator_t abstractions for the osi_*alloc and osi_free functions
|
||||
extern const allocator_t allocator_malloc;
|
||||
extern const allocator_t allocator_calloc;
|
||||
|
||||
char *osi_strdup(const char *str);
|
||||
|
||||
void *osi_malloc_func(size_t size);
|
||||
|
@ -15,16 +15,15 @@ typedef struct list_t {
|
||||
list_node_t *tail;
|
||||
size_t length;
|
||||
list_free_cb free_cb;
|
||||
const allocator_t *allocator;
|
||||
} list_t;
|
||||
|
||||
//static list_node_t *list_free_node_(list_t *list, list_node_t *node);
|
||||
|
||||
// Hidden constructor, only to be used by the hash map for the allocation tracker.
|
||||
// Behaves the same as |list_new|, except you get to specify the allocator.
|
||||
list_t *list_new_internal(list_free_cb callback, const allocator_t *zeroed_allocator)
|
||||
list_t *list_new_internal(list_free_cb callback)
|
||||
{
|
||||
list_t *list = (list_t *)zeroed_allocator->alloc(sizeof(list_t));
|
||||
list_t *list = (list_t *) osi_calloc(sizeof(list_t));
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
@ -32,13 +31,12 @@ list_t *list_new_internal(list_free_cb callback, const allocator_t *zeroed_alloc
|
||||
list->head = list->tail = NULL;
|
||||
list->length = 0;
|
||||
list->free_cb = callback;
|
||||
list->allocator = zeroed_allocator;
|
||||
return list;
|
||||
}
|
||||
|
||||
list_t *list_new(list_free_cb callback)
|
||||
{
|
||||
return list_new_internal(callback, &allocator_calloc);
|
||||
return list_new_internal(callback);
|
||||
}
|
||||
|
||||
void list_free(list_t *list)
|
||||
@ -48,7 +46,7 @@ void list_free(list_t *list)
|
||||
}
|
||||
|
||||
list_clear(list);
|
||||
list->allocator->free(list);
|
||||
osi_free(list);
|
||||
}
|
||||
|
||||
bool list_is_empty(const list_t *list)
|
||||
@ -99,13 +97,12 @@ list_node_t *list_back_node(const list_t *list) {
|
||||
}
|
||||
|
||||
bool list_insert_after(list_t *list, list_node_t *prev_node, void *data) {
|
||||
assert(list != NULL);
|
||||
assert(prev_node != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
list_node_t *node = (list_node_t *)list->allocator->alloc(sizeof(list_node_t));
|
||||
if (!node)
|
||||
return false;
|
||||
assert(list != NULL);
|
||||
assert(prev_node != NULL);
|
||||
assert(data != NULL);
|
||||
list_node_t *node = (list_node_t *) osi_calloc(sizeof(list_node_t));
|
||||
if (!node)
|
||||
return false;
|
||||
|
||||
node->next = prev_node->next;
|
||||
node->data = data;
|
||||
@ -121,8 +118,7 @@ bool list_prepend(list_t *list, void *data)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
list_node_t *node = (list_node_t *)list->allocator->alloc(sizeof(list_node_t));
|
||||
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t));
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
@ -140,8 +136,7 @@ bool list_append(list_t *list, void *data)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
list_node_t *node = (list_node_t *)list->allocator->alloc(sizeof(list_node_t));
|
||||
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t));
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
@ -247,7 +242,7 @@ list_node_t *list_free_node(list_t *list, list_node_t *node)
|
||||
if (list->free_cb) {
|
||||
list->free_cb(node->data);
|
||||
}
|
||||
list->allocator->free(node);
|
||||
osi_free(node);
|
||||
--list->length;
|
||||
|
||||
return next;
|
||||
|
Loading…
x
Reference in New Issue
Block a user