static int get_config_size(const config_t *config) { assert(config != NULL); int w_len = 0, total_size = 0; for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { const section_t *section = (const section_t *)list_node(node); w_len = strlen(section->name) + strlen("[]\n");// format "[section->name]\n" total_size += w_len; for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) { const entry_t *entry = (const entry_t *)list_node(enode); w_len = strlen(entry->key) + strlen(entry->value) + strlen(" = \n");// format "entry->key = entry->value\n" total_size += w_len; } // Only add a separating newline if there are more sections. if (list_next(node) != list_end(config->sections)) { total_size ++; //'\n' } else { break; } } total_size ++; //'\0' return total_size; }
int main(int argc, char *argv[]) { struct list_node first = list_node(1), second = list_node(2), third = list_node(3); list_node_prepend(&first, &head); list_node_prepend(&second, &first); list_node_append(&third, &second); list_node_traverse(&head); list_node_remove(&second); list_node_traverse(&head); return 0; }
// Must be called with monitor held static void schedule_next_instance(alarm_t *alarm, bool force_reschedule) { // If the alarm is currently set and it's at the start of the list, // we'll need to re-schedule since we've adjusted the earliest deadline. bool needs_reschedule = (!list_is_empty(alarms) && list_front(alarms) == alarm); if (alarm->callback) list_remove(alarms, alarm); // Calculate the next deadline for this alarm period_ms_t just_now = now(); period_ms_t ms_into_period = alarm->is_periodic ? ((just_now - alarm->created) % alarm->period) : 0; alarm->deadline = just_now + (alarm->period - ms_into_period); // Add it into the timer list sorted by deadline (earliest deadline first). if (list_is_empty(alarms) || ((alarm_t *)list_front(alarms))->deadline >= alarm->deadline) list_prepend(alarms, alarm); else for (list_node_t *node = list_begin(alarms); node != list_end(alarms); node = list_next(node)) { list_node_t *next = list_next(node); if (next == list_end(alarms) || ((alarm_t *)list_node(next))->deadline >= alarm->deadline) { list_insert_after(alarms, node, alarm); break; } } // If the new alarm has the earliest deadline, we need to re-evaluate our schedule. if (force_reschedule || needs_reschedule || (!list_is_empty(alarms) && list_front(alarms) == alarm)) reschedule_root_alarm(); }
// Runs in exclusion with alarm_cancel and timer_callback. void alarm_set(alarm_t *alarm, period_ms_t deadline, alarm_callback_t cb, void *data) { assert(alarms != NULL); assert(alarm != NULL); assert(cb != NULL); pthread_mutex_lock(&monitor); // If the alarm is currently set and it's at the start of the list, // we'll need to re-schedule since we've adjusted the earliest deadline. bool needs_reschedule = (!list_is_empty(alarms) && list_front(alarms) == alarm); if (alarm->callback) list_remove(alarms, alarm); alarm->deadline = now() + deadline; alarm->callback = cb; alarm->data = data; // Add it into the timer list sorted by deadline (earliest deadline first). if (list_is_empty(alarms)) list_prepend(alarms, alarm); else for (list_node_t *node = list_begin(alarms); node != list_end(alarms); node = list_next(node)) { list_node_t *next = list_next(node); if (next == list_end(alarms) || ((alarm_t *)list_node(next))->deadline >= alarm->deadline) { list_insert_after(alarms, node, alarm); break; } } // If the new alarm has the earliest deadline, we need to re-evaluate our schedule. if (needs_reschedule || (!list_is_empty(alarms) && list_front(alarms) == alarm)) reschedule(); pthread_mutex_unlock(&monitor); }
/******************************************************************************* ** ** Function l2c_process_held_packets ** ** Description This function processes any L2CAP packets that arrived before ** the HCI connection complete arrived. It is a work around for ** badly behaved controllers. ** ** Returns void ** *******************************************************************************/ void l2c_process_held_packets(BOOLEAN timed_out) { if (list_is_empty(l2cb.rcv_pending_q)) { return; } if (!timed_out) { btu_stop_timer(&l2cb.rcv_hold_tle); L2CAP_TRACE_WARNING("L2CAP HOLD CONTINUE"); } else { L2CAP_TRACE_WARNING("L2CAP HOLD TIMEOUT"); } for (const list_node_t *node = list_begin(l2cb.rcv_pending_q); node != list_end(l2cb.rcv_pending_q);) { BT_HDR *p_buf = list_node(node); node = list_next(node); if (!timed_out || (!p_buf->layer_specific) || (--p_buf->layer_specific == 0)) { list_remove(l2cb.rcv_pending_q, p_buf); p_buf->layer_specific = 0xFFFF; l2c_rcv_acl_data(p_buf); } } /* If anyone still in the queue, restart the timeout */ if (!list_is_empty(l2cb.rcv_pending_q)) { btu_start_timer (&l2cb.rcv_hold_tle, BTU_TTYPE_L2CAP_HOLD, BT_1SEC_TIMEOUT); } }
const char *config_section_name(const config_section_node_t *node) { assert(node != NULL); const list_node_t *lnode = (const list_node_t *)node; const section_t *section = (const section_t *)list_node(lnode); return section->name; }
// Must be called with |lock| held. static sco_socket_t *sco_socket_find_locked(uint16_t sco_handle) { for (const list_node_t *node = list_begin(sco_sockets); node != list_end(sco_sockets); node = list_next(node)) { sco_socket_t *sco_socket = (sco_socket_t *)list_node(node); if (sco_socket->sco_handle == sco_handle) return sco_socket; } return NULL; }
static section_t *section_find(const config_t *config, const char *section) { for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { section_t *sec = list_node(node); if (!strcmp(sec->name, section)) return sec; } return NULL; }
bool config_has_key_in_section(config_t *config, char *key, char *key_value) { LOG_DEBUG("key = %s, value = %s", key, key_value); for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { const section_t *section = (const section_t *)list_node(node); for (const list_node_t *node = list_begin(section->entries); node != list_end(section->entries); node = list_next(node)) { entry_t *entry = list_node(node); LOG_DEBUG("entry->key = %s, entry->value = %s", entry->key, entry->value); if (!strcmp(entry->key, key) && !strcmp(entry->value, key_value)) { LOG_DEBUG("%s, the irk aready in the flash.", __func__); return true; } } } return false; }
bool list_contains(const list_t *list, const void *data) { assert(list != NULL); assert(data != NULL); for (const list_node_t *node = list_begin(list); node != list_end(list); node = list_next(node)) { if (list_node(node) == data) return true; } return false; }
TEST_F(ListTest, test_list_prepend_multiple) { int x[] = { 1, 2, 3, 4, 5 }; list_t *list = list_new(NULL); for (size_t i = 0; i < ARRAY_SIZE(x); ++i) list_prepend(list, &x[i]); int i = ARRAY_SIZE(x) - 1; for (const list_node_t *node = list_begin(list); node != list_end(list); node = list_next(node), --i) EXPECT_EQ(list_node(node), &x[i]); list_free(list); }
static entry_t *entry_find(const config_t *config, const char *section, const char *key) { section_t *sec = section_find(config, section); if (!sec) return NULL; for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) { entry_t *entry = list_node(node); if (!strcmp(entry->key, key)) return entry; } return NULL; }
void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb) { if (!queue) return; if (free_cb) for (const list_node_t *node = list_begin(queue->list); node != list_end(queue->list); node = list_next(node)) free_cb(list_node(node)); list_free(queue->list); semaphore_free(queue->enqueue_sem); semaphore_free(queue->dequeue_sem); pthread_mutex_destroy(&queue->lock); free(queue); }
void task_init(void) { task_init_task(0, &task_a_fn); task_init_task(1, &task_b_fn); // Make list circular list_node(task_idle).next = &list_node(task_idle); list_node(task_idle).prev = &list_node(task_idle); current_task = &task_idle; // Insert Task A and B list_insert(&list_node(*current_task), &list_node(tasks[1])); list_insert(&list_node(*current_task), &list_node(tasks[0])); }
void *dict_expr_gen_evaluate(dict_expr *structure, environment *env) { pydict *retptr = (pydict *)malloc(sizeof(pydict)); retptr->type = pydict_t; retptr->keys = list_node(); retptr->values = list_node(); if (!structure->ptr) structure->ptr = structure->expr_head; if (!structure->ptr2) structure->ptr2 = structure->expr_head2; void *key, *val; int pos; while (structure->ptr) { key = gen_evaluate(structure->ptr->content, env); if (env->yield) return 0; val = gen_evaluate(structure->ptr2->content, env); if (env->yield) return 0; if ((pos = list_find(retptr->keys, key)) >= 0) { int ind; list *ptr = retptr->keys; for (ind = 0; ind < pos; ind++) ptr = ptr->next; // del(ptr->content); ptr->content = val; // del(key); } else { list_append_content(retptr->keys, key); list_append_content(retptr->values, val); } structure->ptr = structure->ptr->next; structure->ptr2 = structure->ptr2->next; } return retptr; }
void *set_expr_gen_evaluate(set_expr *structure, environment *env) { pyset *retptr = (pyset *)malloc(sizeof(pyset)); retptr->type = pyset_t; if (!structure->ptr) structure->ptr = structure->expr_head; if (!structure->values) structure->values = list_node(); for ( ; structure->ptr; structure->ptr = structure->ptr->next) { void *val = gen_evaluate(structure->ptr->content, env); if (env->yield) return 0; if (list_find(retptr->values, val) < 0) list_append_content(structure->values, val); } retptr->values = structure->values; structure->values = 0; return retptr; }
void config_set_string(config_t *config, const char *section, const char *key, const char *value) { section_t *sec = section_find(config, section); if (!sec) { sec = section_new(section); list_append(config->sections, sec); } for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) { entry_t *entry = list_node(node); if (!strcmp(entry->key, key)) { free(entry->value); entry->value = strdup(value); return; } } entry_t *entry = entry_new(key, value); list_append(sec->entries, entry); }
void *parenth_form_gen_evaluate(parenth_form *structure, environment *env) { pytuple *retptr = (pytuple *)malloc(sizeof(pytuple)); retptr->type = pytuple_t; if (list_is_empty(structure->expr_head)) return retptr; if (!structure->ptr) structure->ptr = structure->expr_head; if (!structure->values) structure->values = list_node(); for ( ; structure->ptr; structure->ptr = structure->ptr->next) { void *val = gen_evaluate(structure->ptr->content, env); if (env->yield) return 0; list_append_content(structure->values, val); } retptr->values = structure->values; structure->values = 0; return retptr; }
static waiting_command_t *get_waiting_command(command_opcode_t opcode) { pthread_mutex_lock(&commands_pending_response_lock); for (const list_node_t *node = list_begin(commands_pending_response); node != list_end(commands_pending_response); node = list_next(node)) { waiting_command_t *wait_entry = list_node(node); if (!wait_entry || wait_entry->opcode != opcode) continue; list_remove(commands_pending_response, wait_entry); pthread_mutex_unlock(&commands_pending_response_lock); return wait_entry; } pthread_mutex_unlock(&commands_pending_response_lock); return NULL; }
static waiting_command_t *get_waiting_command(command_opcode_t opcode) { command_waiting_response_t *cmd_wait_q = &hci_host_env.cmd_waiting_q; osi_mutex_lock(&cmd_wait_q->commands_pending_response_lock, OSI_MUTEX_MAX_TIMEOUT); for (const list_node_t *node = list_begin(cmd_wait_q->commands_pending_response); node != list_end(cmd_wait_q->commands_pending_response); node = list_next(node)) { waiting_command_t *wait_entry = list_node(node); if (!wait_entry || wait_entry->opcode != opcode) { continue; } list_remove(cmd_wait_q->commands_pending_response, wait_entry); osi_mutex_unlock(&cmd_wait_q->commands_pending_response_lock); return wait_entry; } osi_mutex_unlock(&cmd_wait_q->commands_pending_response_lock); return NULL; }
bool config_save(const config_t *config, const char *filename) { assert(config != NULL); assert(filename != NULL); assert(*filename != '\0'); esp_err_t err; int err_code = 0; nvs_handle fp; char *line = osi_calloc(1024); char *keyname = osi_calloc(sizeof(CONFIG_KEY) + 1); int config_size = get_config_size(config); char *buf = osi_calloc(config_size + 100); if (!line || !buf || !keyname) { err_code |= 0x01; goto error; } err = nvs_open(filename, NVS_READWRITE, &fp); if (err != ESP_OK) { if (err == ESP_ERR_NVS_NOT_INITIALIZED) { LOG_ERROR("%s: NVS not initialized. " "Call nvs_flash_init before initializing bluetooth.", __func__); } err_code |= 0x02; goto error; } int w_cnt, w_cnt_total = 0; for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { const section_t *section = (const section_t *)list_node(node); w_cnt = snprintf(line, 1024, "[%s]\n", section->name); LOG_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, w_cnt + w_cnt_total); memcpy(buf + w_cnt_total, line, w_cnt); w_cnt_total += w_cnt; for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) { const entry_t *entry = (const entry_t *)list_node(enode); LOG_DEBUG("(key, val): (%s, %s)\n", entry->key, entry->value); w_cnt = snprintf(line, 1024, "%s = %s\n", entry->key, entry->value); LOG_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, w_cnt + w_cnt_total); memcpy(buf + w_cnt_total, line, w_cnt); w_cnt_total += w_cnt; } // Only add a separating newline if there are more sections. if (list_next(node) != list_end(config->sections)) { buf[w_cnt_total] = '\n'; w_cnt_total += 1; } else { break; } } buf[w_cnt_total] = '\0'; if (w_cnt_total < CONFIG_FILE_MAX_SIZE) { snprintf(keyname, sizeof(CONFIG_KEY)+1, "%s%d", CONFIG_KEY, 0); err = nvs_set_blob(fp, keyname, buf, w_cnt_total); if (err != ESP_OK) { nvs_close(fp); err_code |= 0x04; goto error; } }else { uint count = (w_cnt_total / CONFIG_FILE_MAX_SIZE); for (int i = 0; i <= count; i++) { snprintf(keyname, sizeof(CONFIG_KEY)+1, "%s%d", CONFIG_KEY, i); if (i == count) { err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, w_cnt_total - i*CONFIG_FILE_MAX_SIZE); LOG_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, w_cnt_total - i*CONFIG_FILE_MAX_SIZE); }else { err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, CONFIG_FILE_MAX_SIZE); LOG_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, CONFIG_FILE_MAX_SIZE); } if (err != ESP_OK) { nvs_close(fp); err_code |= 0x04; goto error; } } } err = nvs_commit(fp); if (err != ESP_OK) { nvs_close(fp); err_code |= 0x08; goto error; } nvs_close(fp); osi_free(line); osi_free(buf); osi_free(keyname); return true; error: if (buf) { osi_free(buf); } if (line) { osi_free(line); } if (keyname) { osi_free(keyname); } if (err_code) { LOG_ERROR("%s, err_code: 0x%x\n", __func__, err_code); } return false; }