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_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;

View file

@ -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();

View file

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

View file

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

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

View file

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

View file

@ -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--;
return list_remove(hash_bucket_list, hash_map_entry);
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 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,

View file

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

View file

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