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:
Jiang Jiang Jian 2018-09-13 10:49:26 +08:00
commit 60a9462f6e
11 changed files with 68 additions and 174 deletions

View file

@ -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;
}

View file

@ -19,7 +19,6 @@
#include "common/bt_defs.h" #include "common/bt_defs.h"
#include "common/bt_trace.h" #include "common/bt_trace.h"
#include "stack/bt_types.h" #include "stack/bt_types.h"
#include "hci/buffer_allocator.h"
#include "osi/fixed_queue.h" #include "osi/fixed_queue.h"
#include "hci/hci_hal.h" #include "hci/hci_hal.h"
#include "hci/hci_internals.h" #include "hci/hci_internals.h"
@ -54,7 +53,6 @@ static const uint16_t outbound_event_types[] = {
}; };
typedef struct { typedef struct {
const allocator_t *allocator;
size_t buffer_size; size_t buffer_size;
fixed_queue_t *rx_q; fixed_queue_t *rx_q;
} hci_hal_env_t; } hci_hal_env_t;
@ -82,7 +80,6 @@ static void hci_hal_env_init(
assert(buffer_size > 0); assert(buffer_size > 0);
assert(max_buffer_count > 0); assert(max_buffer_count > 0);
hci_hal_env.allocator = buffer_allocator_get_interface();
hci_hal_env.buffer_size = buffer_size; hci_hal_env.buffer_size = buffer_size;
hci_hal_env.rx_q = fixed_queue_new(max_buffer_count); 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) 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; 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); STREAM_TO_UINT8(len, stream);
HCI_TRACE_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n", HCI_TRACE_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n",
packet->len, len); packet->len, len);
hci_hal_env.allocator->free(packet); osi_free(packet);
return; return;
} }
if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) { if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
HCI_TRACE_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x," HCI_TRACE_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x,"
" min %x, max %x\n", __func__, type, " min %x, max %x\n", __func__, type,
DATA_TYPE_ACL, DATA_TYPE_EVENT); DATA_TYPE_ACL, DATA_TYPE_EVENT);
hci_hal_env.allocator->free(packet); osi_free(packet);
return; return;
} }
hdr_size = preamble_sizes[type - 1]; hdr_size = preamble_sizes[type - 1];
if (packet->len < hdr_size) { if (packet->len < hdr_size) {
HCI_TRACE_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d", HCI_TRACE_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d",
type, packet->len, hdr_size); type, packet->len, hdr_size);
hci_hal_env.allocator->free(packet); osi_free(packet);
return; return;
} }
if (type == DATA_TYPE_ACL) { 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) { if ((length + hdr_size) != packet->len) {
HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d " HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
"pkt_len=%d", type, hdr_size, length, packet->len); "pkt_len=%d", type, hdr_size, length, packet->len);
hci_hal_env.allocator->free(packet); osi_free(packet);
return; return;
} }
#if SCAN_QUEUE_CONGEST_CHECK #if SCAN_QUEUE_CONGEST_CHECK
if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) { if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) {
HCI_TRACE_ERROR("BtuQueue is congested"); HCI_TRACE_ERROR("BtuQueue is congested");
hci_hal_env.allocator->free(packet); osi_free(packet);
return; return;
} }
#endif #endif
@ -324,7 +321,8 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
} }
pkt_size = BT_HDR_SIZE + 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) { if (!pkt) {
HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__); HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
return -1; return -1;

View file

@ -27,7 +27,6 @@
#include "hci/hci_layer.h" #include "hci/hci_layer.h"
#include "osi/allocator.h" #include "osi/allocator.h"
#include "hci/packet_fragmenter.h" #include "hci/packet_fragmenter.h"
#include "hci/buffer_allocator.h"
#include "osi/list.h" #include "osi/list.h"
#include "osi/alarm.h" #include "osi/alarm.h"
#include "osi/thread.h" #include "osi/thread.h"
@ -78,7 +77,6 @@ static xQueueHandle xHciHostQueue;
static bool hci_host_startup_flag; static bool hci_host_startup_flag;
// Modules we import and callbacks we export // Modules we import and callbacks we export
static const allocator_t *buffer_allocator;
static const hci_hal_t *hal; static const hci_hal_t *hal;
static const hci_hal_callbacks_t hal_callbacks; static const hci_hal_callbacks_t hal_callbacks;
static const packet_fragmenter_t *packet_fragmenter; 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; command_waiting_response_t *cmd_wait_q;
if (hci_host_env.command_queue) { 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) { 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; 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){ if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE){
packet_fragmenter->fragment_and_dispatch(wait_entry->command); packet_fragmenter->fragment_and_dispatch(wait_entry->command);
buffer_allocator->free(wait_entry->command); osi_free(wait_entry->command);
osi_free(wait_entry); osi_free(wait_entry);
return; 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); hal->transmit_data(type, packet->data + packet->offset, packet->len);
if (event != MSG_STACK_TO_HC_HCI_CMD && send_transmit_finished) { 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) static void fragmenter_transmit_finished(BT_HDR *packet, bool all_fragments_sent)
{ {
if (all_fragments_sent) { if (all_fragments_sent) {
buffer_allocator->free(packet); osi_free(packet);
} else { } else {
// This is kind of a weird case, since we're dispatching a partially sent packet // This is kind of a weird case, since we're dispatching a partially sent packet
// up to a higher layer. // up to a higher layer.
// TODO(zachoverflow): rework upper layer so this isn't necessary. // 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 /* 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 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 it has a callback, it's responsible for freeing the packet
if (event_code == HCI_COMMAND_STATUS_EVT || if (event_code == HCI_COMMAND_STATUS_EVT ||
(!wait_entry->complete_callback && !wait_entry->complete_future)) { (!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 it has a callback, it's responsible for freeing the command
if (event_code == HCI_COMMAND_COMPLETE_EVT || !wait_entry->status_callback) { 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); osi_free(wait_entry);
} else { } else {
buffer_allocator->free(packet); osi_free(packet);
} }
return true; return true;
@ -506,7 +504,7 @@ static void dispatch_reassembled(BT_HDR *packet)
// Events should already have been dispatched before this point // Events should already have been dispatched before this point
//Tell Up-layer received packet. //Tell Up-layer received packet.
if (btu_task_post(SIG_BTU_HCI_MSG, packet, TASK_POST_BLOCKING) != TASK_POST_SUCCESS) { 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() const hci_t *hci_layer_get_interface()
{ {
buffer_allocator = buffer_allocator_get_interface();
hal = hci_hal_h4_get_interface(); hal = hci_hal_h4_get_interface();
packet_fragmenter = packet_fragmenter_get_interface(); packet_fragmenter = packet_fragmenter_get_interface();

View file

@ -20,14 +20,12 @@
#include "osi/allocator.h" #include "osi/allocator.h"
#include "stack/bt_types.h" #include "stack/bt_types.h"
#include "hci/buffer_allocator.h"
#include "stack/hcidefs.h" #include "stack/hcidefs.h"
#include "stack/hcimsgs.h" #include "stack/hcimsgs.h"
#include "hci/hci_internals.h" #include "hci/hci_internals.h"
#include "hci/hci_layer.h" #include "hci/hci_layer.h"
#include "hci/hci_packet_factory.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_packet(size_t data_size);
static BT_HDR *make_command_no_params(uint16_t opcode); 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) 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); assert(ret);
ret->event = 0; ret->event = 0;
ret->offset = 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() const hci_packet_factory_t *hci_packet_factory_get_interface()
{ {
buffer_allocator = buffer_allocator_get_interface();
return &interface; return &interface;
} }

View file

@ -18,7 +18,6 @@
#include "common/bt_defs.h" #include "common/bt_defs.h"
#include "hci/buffer_allocator.h"
#include "stack/bt_types.h" #include "stack/bt_types.h"
#include "stack/hcimsgs.h" #include "stack/hcimsgs.h"
#include "hci/hci_layer.h" #include "hci/hci_layer.h"
@ -26,8 +25,6 @@
static const command_opcode_t NO_OPCODE_CHECKING = 0; static const command_opcode_t NO_OPCODE_CHECKING = 0;
static const allocator_t *buffer_allocator;
static uint8_t *read_command_complete_header( static uint8_t *read_command_complete_header(
BT_HDR *response, BT_HDR *response,
command_opcode_t expected_opcode, 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 */); 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( 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_UINT8(*sco_data_size_ptr, stream);
STREAM_TO_UINT16(*acl_buffer_count_ptr, stream); STREAM_TO_UINT16(*acl_buffer_count_ptr, stream);
STREAM_TO_UINT16(*sco_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( 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->manufacturer, stream);
STREAM_TO_UINT16(bt_version->lmp_subversion, stream); STREAM_TO_UINT16(bt_version->lmp_subversion, stream);
buffer_allocator->free(response); osi_free(response);
} }
static void parse_read_bd_addr_response( static void parse_read_bd_addr_response(
@ -82,7 +79,7 @@ static void parse_read_bd_addr_response(
assert(stream != NULL); assert(stream != NULL);
STREAM_TO_BDADDR(address_ptr->address, stream); STREAM_TO_BDADDR(address_ptr->address, stream);
buffer_allocator->free(response); osi_free(response);
} }
static void parse_read_local_supported_commands_response( static void parse_read_local_supported_commands_response(
@ -95,7 +92,7 @@ static void parse_read_local_supported_commands_response(
assert(stream != NULL); assert(stream != NULL);
STREAM_TO_ARRAY(supported_commands_ptr, stream, (int)supported_commands_length); 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( 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__); "THIS MAY INDICATE A FIRMWARE/CONTROLLER ISSUE.", __func__);
} }
buffer_allocator->free(response); osi_free(response);
} }
static void parse_ble_read_white_list_size_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); assert(stream != NULL);
STREAM_TO_UINT8(*white_list_size_ptr, stream); STREAM_TO_UINT8(*white_list_size_ptr, stream);
buffer_allocator->free(response); osi_free(response);
} }
static void parse_ble_read_buffer_size_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_UINT16(*data_size_ptr, stream);
STREAM_TO_UINT8(*acl_buffer_count_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( static void parse_ble_read_supported_states_response(
@ -157,7 +154,7 @@ static void parse_ble_read_supported_states_response(
assert(stream != NULL); assert(stream != NULL);
STREAM_TO_ARRAY(supported_states, stream, (int)supported_states_size); 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( 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); assert(stream != NULL);
STREAM_TO_ARRAY(supported_features->as_array, stream, (int)sizeof(bt_device_features_t)); 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( 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 */); 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); 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( 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 */); 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_length_ptr, stream);
STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream); STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream);
buffer_allocator->free(response); osi_free(response);
} }
// Internal functions // Internal functions
@ -255,7 +252,6 @@ static const hci_packet_parser_t interface = {
const hci_packet_parser_t *hci_packet_parser_get_interface() const hci_packet_parser_t *hci_packet_parser_get_interface()
{ {
buffer_allocator = buffer_allocator_get_interface();
return &interface; return &interface;
} }

View file

@ -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_*/

View file

@ -19,7 +19,6 @@
#include "common/bt_trace.h" #include "common/bt_trace.h"
#include "common/bt_defs.h" #include "common/bt_defs.h"
#include "device/controller.h" #include "device/controller.h"
#include "hci/buffer_allocator.h"
#include "hci/hci_internals.h" #include "hci/hci_internals.h"
#include "hci/hci_layer.h" #include "hci/hci_layer.h"
#include "hci/packet_fragmenter.h" #include "hci/packet_fragmenter.h"
@ -44,7 +43,6 @@
// Our interface and callbacks // Our interface and callbacks
static const packet_fragmenter_t interface; static const packet_fragmenter_t interface;
static const allocator_t *buffer_allocator;
static const controller_t *controller; static const controller_t *controller;
static const packet_fragmenter_callbacks_t *callbacks; static const packet_fragmenter_callbacks_t *callbacks;
static hash_map_t *partial_packets; static hash_map_t *partial_packets;
@ -153,7 +151,7 @@ static void reassemble_and_dispatch(BT_HDR *packet)
if (partial_packet) { if (partial_packet) {
HCI_TRACE_WARNING("%s found unfinished packet for handle with start packet. Dropping old.\n", __func__); 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); 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; 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); callbacks->reassembled(packet);
return; return;
} }
partial_packet = (BT_HDR *)osi_calloc(full_length + sizeof(BT_HDR));
partial_packet = (BT_HDR *)buffer_allocator->alloc(full_length + sizeof(BT_HDR));
partial_packet->event = packet->event; partial_packet->event = packet->event;
partial_packet->len = full_length; partial_packet->len = full_length;
partial_packet->offset = packet->len; 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); hash_map_set(partial_packets, (void *)(uintptr_t)handle, partial_packet);
// Free the old packet buffer, since we don't need it anymore // Free the old packet buffer, since we don't need it anymore
buffer_allocator->free(packet); osi_free(packet);
} else { } else {
if (!partial_packet) { if (!partial_packet) {
HCI_TRACE_ERROR("%s got continuation for unknown packet. Dropping it.\n", __func__); HCI_TRACE_ERROR("%s got continuation for unknown packet. Dropping it.\n", __func__);
buffer_allocator->free(packet); osi_free(packet);
return; 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 // Free the old packet buffer, since we don't need it anymore
buffer_allocator->free(packet); osi_free(packet);
partial_packet->offset = projected_offset; partial_packet->offset = projected_offset;
if (partial_packet->offset == partial_packet->len) { 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() const packet_fragmenter_t *packet_fragmenter_get_interface()
{ {
controller = controller_get_interface(); controller = controller_get_interface();
buffer_allocator = buffer_allocator_get_interface();
return &interface; return &interface;
} }

View file

@ -26,7 +26,7 @@ extern void vPortFree(void *pv);
#ifdef CONFIG_BLUEDROID_MEM_DEBUG #ifdef CONFIG_BLUEDROID_MEM_DEBUG
#define OSI_MEM_DBG_INFO_MAX 1024 #define OSI_MEM_DBG_INFO_MAX 1024*3
typedef struct { typedef struct {
void *p; void *p;
int size; int size;
@ -175,13 +175,3 @@ void osi_free_func(void *ptr)
#endif #endif
free(ptr); free(ptr);
} }
const allocator_t allocator_malloc = {
osi_malloc_func,
osi_free_func
};
const allocator_t allocator_calloc = {
osi_calloc_func,
osi_free_func
};

View file

@ -35,12 +35,11 @@ typedef struct hash_map_t {
hash_index_fn hash_fn; hash_index_fn hash_fn;
key_free_fn key_fn; key_free_fn key_fn;
data_free_fn data_fn; data_free_fn data_fn;
const allocator_t *allocator;
key_equality_fn keys_are_equal; key_equality_fn keys_are_equal;
} hash_map_t; } hash_map_t;
// Hidden constructor for list, only to be used by us. // 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 void bucket_free_(void *data);
static bool default_key_equality(const void *x, const void *y); 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, hash_index_fn hash_fn,
key_free_fn key_fn, key_free_fn key_fn,
data_free_fn data_fn, data_free_fn data_fn,
key_equality_fn equality_fn, key_equality_fn equality_fn)
const allocator_t *zeroed_allocator)
{ {
assert(hash_fn != NULL); assert(hash_fn != NULL);
assert(num_bucket > 0); assert(num_bucket > 0);
assert(zeroed_allocator != NULL); hash_map_t *hash_map = osi_calloc(sizeof(hash_map_t));
hash_map_t *hash_map = zeroed_allocator->alloc(sizeof(hash_map_t));
if (hash_map == NULL) { if (hash_map == NULL) {
return NULL; return NULL;
} }
@ -69,13 +65,12 @@ hash_map_t *hash_map_new_internal(
hash_map->hash_fn = hash_fn; hash_map->hash_fn = hash_fn;
hash_map->key_fn = key_fn; hash_map->key_fn = key_fn;
hash_map->data_fn = data_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->keys_are_equal = equality_fn ? equality_fn : default_key_equality;
hash_map->num_bucket = num_bucket; 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) { if (hash_map->bucket == NULL) {
zeroed_allocator->free(hash_map); osi_free(hash_map);
return NULL; return NULL;
} }
return hash_map; return hash_map;
@ -88,7 +83,7 @@ hash_map_t *hash_map_new(
data_free_fn data_fn, data_free_fn data_fn,
key_equality_fn equality_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) void hash_map_free(hash_map_t *hash_map)
@ -97,8 +92,8 @@ void hash_map_free(hash_map_t *hash_map)
return; return;
} }
hash_map_clear(hash_map); hash_map_clear(hash_map);
hash_map->allocator->free(hash_map->bucket); osi_free(hash_map->bucket);
hash_map->allocator->free(hash_map); 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; hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket;
if (hash_map->bucket[hash_key].list == NULL) { 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) { if (hash_map->bucket[hash_key].list == NULL) {
return false; return false;
} }
@ -153,7 +148,7 @@ bool hash_map_set(hash_map_t *hash_map, const void *key, void *data)
} else { } else {
hash_map->hash_size++; 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) { if (hash_map_entry == NULL) {
return false; return false;
} }
@ -178,8 +173,13 @@ bool hash_map_erase(hash_map_t *hash_map, const void *key)
} }
hash_map->hash_size--; hash_map->hash_size--;
bool remove = list_remove(hash_bucket_list, hash_map_entry);
return 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 remove;
} }
void *hash_map_get(const hash_map_t *hash_map, const void *key) 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) { if (hash_map->data_fn) {
hash_map->data_fn(hash_map_entry->data); 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, static hash_map_entry_t *find_bucket_entry_(list_t *hash_bucket_list,

View file

@ -24,18 +24,6 @@
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "sdkconfig.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); char *osi_strdup(const char *str);
void *osi_malloc_func(size_t size); void *osi_malloc_func(size_t size);

View file

@ -15,16 +15,15 @@ typedef struct list_t {
list_node_t *tail; list_node_t *tail;
size_t length; size_t length;
list_free_cb free_cb; list_free_cb free_cb;
const allocator_t *allocator;
} list_t; } list_t;
//static list_node_t *list_free_node_(list_t *list, list_node_t *node); //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. // 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. // 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) { if (!list) {
return NULL; 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->head = list->tail = NULL;
list->length = 0; list->length = 0;
list->free_cb = callback; list->free_cb = callback;
list->allocator = zeroed_allocator;
return list; return list;
} }
list_t *list_new(list_free_cb callback) 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) void list_free(list_t *list)
@ -48,7 +46,7 @@ void list_free(list_t *list)
} }
list_clear(list); list_clear(list);
list->allocator->free(list); osi_free(list);
} }
bool list_is_empty(const list_t *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) { bool list_insert_after(list_t *list, list_node_t *prev_node, void *data) {
assert(list != NULL); assert(list != NULL);
assert(prev_node != NULL); assert(prev_node != NULL);
assert(data != NULL); assert(data != NULL);
list_node_t *node = (list_node_t *) osi_calloc(sizeof(list_node_t));
list_node_t *node = (list_node_t *)list->allocator->alloc(sizeof(list_node_t)); if (!node)
if (!node) return false;
return false;
node->next = prev_node->next; node->next = prev_node->next;
node->data = data; node->data = data;
@ -121,8 +118,7 @@ bool list_prepend(list_t *list, void *data)
{ {
assert(list != NULL); assert(list != NULL);
assert(data != NULL); assert(data != NULL);
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t));
list_node_t *node = (list_node_t *)list->allocator->alloc(sizeof(list_node_t));
if (!node) { if (!node) {
return false; return false;
} }
@ -140,8 +136,7 @@ bool list_append(list_t *list, void *data)
{ {
assert(list != NULL); assert(list != NULL);
assert(data != NULL); assert(data != NULL);
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t));
list_node_t *node = (list_node_t *)list->allocator->alloc(sizeof(list_node_t));
if (!node) { if (!node) {
return false; return false;
} }
@ -247,7 +242,7 @@ list_node_t *list_free_node(list_t *list, list_node_t *node)
if (list->free_cb) { if (list->free_cb) {
list->free_cb(node->data); list->free_cb(node->data);
} }
list->allocator->free(node); osi_free(node);
--list->length; --list->length;
return next; return next;