Repository: incubator-mynewt-tadpole Updated Branches: refs/heads/master 29ce5cdc6 -> f42a66b19
Update tadpole to include the latest larva code. Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/commit/f42a66b1 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/tree/f42a66b1 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/diff/f42a66b1 Branch: refs/heads/master Commit: f42a66b19424a81e69492797df5d2a834725f2e6 Parents: 29ce5cd Author: Christopher Collins <[email protected]> Authored: Fri Dec 18 17:23:27 2015 -0800 Committer: Christopher Collins <[email protected]> Committed: Fri Dec 18 17:23:27 2015 -0800 ---------------------------------------------------------------------- .gitignore | 9 ++ hw/hal/include/hal/hal_flash.h | 1 + hw/hal/include/hal/hal_flash_int.h | 1 + hw/hal/include/hal/hal_spim.h | 44 -------- hw/hal/include/hal/hal_system.h | 10 +- hw/hal/src/hal_flash.c | 12 +++ hw/mcu/native/src/hal_flash.c | 4 +- libs/os/include/os/endian.h | 89 ++++++++++++++++ libs/os/include/os/os_mbuf.h | 23 +++++ libs/os/include/os/os_mutex.h | 2 +- libs/os/include/os/os_sem.h | 2 +- libs/os/include/os/os_task.h | 15 ++- libs/os/include/os/queue.h | 2 +- libs/os/src/arch/sim/os_fault.c | 1 + libs/os/src/os_eventq.c | 1 + libs/os/src/os_info.c | 4 +- libs/os/src/os_mbuf.c | 175 +++++++++++++++++++++++++------- libs/os/src/os_mutex.c | 19 ++-- libs/os/src/os_sched.c | 15 ++- libs/os/src/os_sem.c | 11 +- libs/os/src/test/mbuf_test.c | 93 ++++++++++++++++- libs/os/src/test/mutex_test.c | 9 ++ libs/os/src/test/sem_test.c | 2 +- libs/util/include/util/base64.h | 26 +++++ libs/util/src/base64.c | 167 ++++++++++++++++++++++++++++++ libs/util/src/flash_map.c | 49 +++++++-- libs/util/src/stats.c | 3 + 27 files changed, 666 insertions(+), 123 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index b146445..2f35cd4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,10 @@ +.repo.db +bin +obj +tags +.gdb_history +*~ .nest +.DS_Store +*.swp +*.swo http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/hw/hal/include/hal/hal_flash.h ---------------------------------------------------------------------- diff --git a/hw/hal/include/hal/hal_flash.h b/hw/hal/include/hal/hal_flash.h index be3b358..787e9c2 100644 --- a/hw/hal/include/hal/hal_flash.h +++ b/hw/hal/include/hal/hal_flash.h @@ -25,6 +25,7 @@ int hal_flash_write(uint8_t flash_id, uint32_t address, const void *src, uint32_t num_bytes); int hal_flash_erase_sector(uint8_t flash_id, uint32_t sector_address); int hal_flash_erase(uint8_t flash_id, uint32_t address, uint32_t num_bytes); +uint8_t hal_flash_align(uint8_t flash_id); int hal_flash_init(void); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/hw/hal/include/hal/hal_flash_int.h ---------------------------------------------------------------------- diff --git a/hw/hal/include/hal/hal_flash_int.h b/hw/hal/include/hal/hal_flash_int.h index ab7e159..34cd2c4 100644 --- a/hw/hal/include/hal/hal_flash_int.h +++ b/hw/hal/include/hal/hal_flash_int.h @@ -34,6 +34,7 @@ struct hal_flash { uint32_t hf_base_addr; uint32_t hf_size; int hf_sector_cnt; + int hf_align; /* Alignment requirement. 1 if unrestricted. */ }; /* http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/hw/hal/include/hal/hal_spim.h ---------------------------------------------------------------------- diff --git a/hw/hal/include/hal/hal_spim.h b/hw/hal/include/hal/hal_spim.h deleted file mode 100644 index fa1eeeb..0000000 --- a/hw/hal/include/hal/hal_spim.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (c) 2015 Runtime 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 H_HAL_SPIM_H_ -#define H_HAL_SPIM_H_ - -#include <inttypes.h> - -/** - * - * hal_spim_init() - * - * Sets up a SPI master port ready for data transfer. - * Mapping logical port number to pins is dictated by BSP. - */ -int hal_spim_init(int port, int mode, int speed); - -/* - * hal_spim_select()/hal_spim_deselect. - * Assert and deassert chip select for the target, respectively. - */ -int hal_spim_select(int port); -int hal_spim_deselect(int port); - -/** - * - * hal_spim_txrx() - * Initiate data transfer. Specify TX data or RX data, or both. - */ -int hal_spim_txrx(int port, void *tx_buf, int tx_len, void *rx_buf, int rx_len); - -#endif /* H_HAL_SPIM_H_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/hw/hal/include/hal/hal_system.h ---------------------------------------------------------------------- diff --git a/hw/hal/include/hal/hal_system.h b/hw/hal/include/hal/hal_system.h index 19f5ed1..1cf43c4 100644 --- a/hw/hal/include/hal/hal_system.h +++ b/hw/hal/include/hal/hal_system.h @@ -4,7 +4,7 @@ * 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 @@ -17,6 +17,14 @@ #ifndef H_HAL_SYSTEM_ #define H_HAL_SYSTEM_ +/* + * System reset. + */ void system_reset(void) __attribute((noreturn)); +/* + * Called by bootloader to start loaded program. + */ +void system_start(void *img_start) __attribute((noreturn)); + #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/hw/hal/src/hal_flash.c ---------------------------------------------------------------------- diff --git a/hw/hal/src/hal_flash.c b/hw/hal/src/hal_flash.c index 90fd985..ef4e35a 100644 --- a/hw/hal/src/hal_flash.c +++ b/hw/hal/src/hal_flash.c @@ -39,6 +39,18 @@ hal_flash_init(void) return rc; } +uint8_t +hal_flash_align(uint8_t flash_id) +{ + const struct hal_flash *hf; + + hf = bsp_flash_dev(flash_id); + if (!hf) { + return 1; + } + return hf->hf_align; +} + uint32_t hal_flash_sector_size(const struct hal_flash *hf, int sec_idx) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/hw/mcu/native/src/hal_flash.c ---------------------------------------------------------------------- diff --git a/hw/mcu/native/src/hal_flash.c b/hw/mcu/native/src/hal_flash.c index 98eb6df..5fc3e6c 100644 --- a/hw/mcu/native/src/hal_flash.c +++ b/hw/mcu/native/src/hal_flash.c @@ -65,6 +65,7 @@ const struct hal_flash native_flash_dev = { .hf_base_addr = 0, .hf_size = 1024 * 1024, .hf_sector_cnt = FLASH_NUM_AREAS, + .hf_align = 1 }; static void @@ -85,7 +86,7 @@ flash_native_file_open(char *name) } file = open(name, O_RDWR); if (file < 0) { - file = open(name, O_RDWR | O_CREAT); + file = open(name, O_RDWR | O_CREAT, 0660); assert(file > 0); created = 1; if (ftruncate(file, native_flash_dev.hf_size) < 0) { @@ -155,6 +156,7 @@ flash_native_write_internal(uint32_t address, const void *src, uint32_t length, static int native_flash_write(uint32_t address, const void *src, uint32_t length) { + assert(address % native_flash_dev.hf_align == 0); return flash_native_write_internal(address, src, length, 0); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/include/os/endian.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/endian.h b/libs/os/include/os/endian.h new file mode 100644 index 0000000..c8c838a --- /dev/null +++ b/libs/os/include/os/endian.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2015 Runtime 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 H_ENDIAN_ +#define H_ENDIAN_ + +#include <inttypes.h> + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +#ifndef ntohll +#define ntohll(x) ((uint64_t)(x)) +#endif + +#ifndef htonll +#define htonll(x) ((uint64_t)(x)) +#endif + +#ifndef ntohl +#define ntohl(x) ((uint32_t)(x)) +#endif + +#ifndef htonl +#define htonl(x) ((uint32_t)(x)) +#endif + +#ifndef ntohs +#define ntohs(x) ((uint16_t)(x)) +#endif + +#ifndef htons +#define htons(x) ((uint16_t)(x)) +#endif + +#else + +#ifndef ntohll +#define ntohll(x) ((uint64_t) \ + ((((x) & 0xff00000000000000ull) >> 56) | \ + (((x) & 0x00ff000000000000ull) >> 40) | \ + (((x) & 0x0000ff0000000000ull) >> 24) | \ + (((x) & 0x000000ff00000000ull) >> 8) | \ + (((x) & 0x00000000ff000000ull) << 8) | \ + (((x) & 0x0000000000ff0000ull) << 24) | \ + (((x) & 0x000000000000ff00ull) << 40) | \ + (((x) & 0x00000000000000ffull) << 56))) +#endif + +#ifndef htonll +#define htonll ntohll +#endif + +#ifndef ntohl +#define ntohl(x) ((uint32_t) \ + ((((x) & 0xff000000) >> 24) | \ + (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x000000ff) << 24))) +#endif + +#ifndef htonl +#define htonl ntohl +#endif + +#ifndef htons +#define htons(x) ((uint16_t) \ + ((((x) & 0xff00) >> 8) | \ + (((x) & 0x00ff) << 8))) +#endif + +#ifndef ntohs +#define ntohs htons +#endif + +#endif +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/include/os/os_mbuf.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/os_mbuf.h b/libs/os/include/os/os_mbuf.h index 881ddba..9eaee38 100644 --- a/libs/os/include/os/os_mbuf.h +++ b/libs/os/include/os/os_mbuf.h @@ -17,6 +17,7 @@ #ifndef _OS_MBUF_H #define _OS_MBUF_H +#include "os/queue.h" #include "os/os_eventq.h" /** @@ -40,6 +41,11 @@ struct os_mbuf_pool { * The memory pool which to allocate mbufs out of */ struct os_mempool *omp_pool; + + /** + * Link to the next mbuf pool for system memory pools. + */ + STAILQ_ENTRY(os_mbuf_pool) omp_next; }; @@ -126,6 +132,12 @@ struct os_mqueue { #define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \ (struct os_mbuf *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf)) +/** + * Gets the length of an entire mbuf chain. The specified mbuf must have a + * packet header. + */ +#define OS_MBUF_PKTLEN(__om) (OS_MBUF_PKTHDR(__om)->omp_len) + /* * Access the data of a mbuf, and cast it to type * @@ -201,6 +213,16 @@ struct os_mbuf *os_mqueue_get(struct os_mqueue *); /* Put an element in a mbuf queue */ int os_mqueue_put(struct os_mqueue *, struct os_eventq *, struct os_mbuf *); +/* Register an mbuf pool with the system pool registry */ +int os_msys_register(struct os_mbuf_pool *); + +/* Return a mbuf from the system pool, given an indicative mbuf size */ +struct os_mbuf *os_msys_get(uint16_t dsize, uint16_t leadingspace); + +/* Return a packet header mbuf from the system pool */ +struct os_mbuf *os_msys_get_pkthdr(uint16_t dsize, uint16_t pkthdr_len); + + /* Initialize a mbuf pool */ int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp, uint16_t, uint16_t); @@ -237,5 +259,6 @@ struct os_mbuf *os_mbuf_prepend(struct os_mbuf *om, int len); int os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len); void os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second); void *os_mbuf_extend(struct os_mbuf *om, uint16_t len); +struct os_mbuf *os_mbuf_pullup(struct os_mbuf *om, uint16_t len); #endif /* _OS_MBUF_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/include/os/os_mutex.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/os_mutex.h b/libs/os/include/os/os_mutex.h index 716ba60..a16c370 100644 --- a/libs/os/include/os/os_mutex.h +++ b/libs/os/include/os/os_mutex.h @@ -22,11 +22,11 @@ struct os_mutex { + SLIST_HEAD(, os_task) mu_head; /* chain of waiting tasks */ uint8_t _pad; uint8_t mu_prio; /* owner's default priority*/ uint16_t mu_level; /* call nesting level */ struct os_task *mu_owner; /* owners task */ - SLIST_HEAD(, os_task) mu_head; /* chain of waiting tasks */ }; /* http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/include/os/os_sem.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/os_sem.h b/libs/os/include/os/os_sem.h index 73e84ee..b0eb8bf 100644 --- a/libs/os/include/os/os_sem.h +++ b/libs/os/include/os/os_sem.h @@ -21,9 +21,9 @@ struct os_sem { + SLIST_HEAD(, os_task) sem_head; /* chain of waiting tasks */ uint16_t _pad; uint16_t sem_tokens; /* # of tokens */ - SLIST_HEAD(, os_task) sem_head; /* chain of waiting tasks */ }; /* http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/include/os/os_task.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/os_task.h b/libs/os/include/os/os_task.h index 3f75432..ae44a73 100644 --- a/libs/os/include/os/os_task.h +++ b/libs/os/include/os/os_task.h @@ -29,6 +29,18 @@ #define OS_TASK_NAME_SIZE (36) #endif +/* + * Generic "object" structure. All objects that a task can wait on must + * have a SLIST_HEAD(, os_task) head_name as the first element in the object + * structure. The element 'head_name' can be any name. See os_mutex.h or + * os_sem.h for an example. + */ +struct os_task_obj +{ + SLIST_HEAD(, os_task) obj_head; /* chain of waiting tasks */ +}; + +/* Task states */ typedef enum os_task_state { OS_TASK_READY = 1, OS_TASK_SLEEP = 2 @@ -37,6 +49,7 @@ typedef enum os_task_state { /* Task flags */ #define OS_TASK_FLAG_NO_TIMEOUT (0x0001U) #define OS_TASK_FLAG_SEM_WAIT (0x0002U) +#define OS_TASK_FLAG_MUTEX_WAIT (0x0004U) typedef void (*os_task_func_t)(void *); @@ -54,7 +67,7 @@ struct os_task { os_task_func_t t_func; void *t_arg; - struct os_mutex *t_mutex; + void *t_obj; struct os_sanity_check t_sanity_check; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/include/os/queue.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/queue.h b/libs/os/include/os/queue.h index 39826dd..4f5cacf 100755 --- a/libs/os/include/os/queue.h +++ b/libs/os/include/os/queue.h @@ -242,7 +242,7 @@ struct { \ (STAILQ_EMPTY(head) ? \ NULL : \ ((struct type *) \ - ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + ((char *)((head)->stqh_last) - offsetof(struct type, field)))) #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/arch/sim/os_fault.c ---------------------------------------------------------------------- diff --git a/libs/os/src/arch/sim/os_fault.c b/libs/os/src/arch/sim/os_fault.c index 8bd8fbe..f6aa6cb 100644 --- a/libs/os/src/arch/sim/os_fault.c +++ b/libs/os/src/arch/sim/os_fault.c @@ -27,4 +27,5 @@ __assert_func(const char *file, int line, const char *func, const char *e) snprintf(msg, sizeof(msg), "assert at %s:%d\n", file, line); write(1, msg, strlen(msg)); + _exit(1); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/os_eventq.c ---------------------------------------------------------------------- diff --git a/libs/os/src/os_eventq.c b/libs/os/src/os_eventq.c index 3515a22..ca729db 100644 --- a/libs/os/src/os_eventq.c +++ b/libs/os/src/os_eventq.c @@ -48,6 +48,7 @@ os_eventq_put2(struct os_eventq *evq, struct os_event *ev, int isr) resched = 0; if (evq->evq_task) { os_sched_wakeup(evq->evq_task); + evq->evq_task = NULL; resched = 1; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/os_info.c ---------------------------------------------------------------------- diff --git a/libs/os/src/os_info.c b/libs/os/src/os_info.c index ebb6f12..2387cdd 100644 --- a/libs/os/src/os_info.c +++ b/libs/os/src/os_info.c @@ -69,7 +69,7 @@ shell_os_tasks_display(int argc, char **argv) name = NULL; found = 0; - if (argv[1] != NULL && strcmp(argv[1], "")) { + if (argc > 1 && strcmp(argv[1], "")) { name = argv[1]; } @@ -95,7 +95,7 @@ shell_os_tasks_display(int argc, char **argv) } console_printf(" %s (prio: %u, nw: %u, flags: 0x%x, " - "ssize: %u, cswcnt: %lu, tot_run_time: %ums)", + "ssize: %u, cswcnt: %lu, tot_run_time: %ums)\n", info[i].oti_name, info[i].oti_prio, info[i].oti_next_wakeup, info[i].oti_flags, info[i].oti_stack_size, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/os_mbuf.c ---------------------------------------------------------------------- diff --git a/libs/os/src/os_mbuf.c b/libs/os/src/os_mbuf.c index b1be0fc..f14466a 100644 --- a/libs/os/src/os_mbuf.c +++ b/libs/os/src/os_mbuf.c @@ -54,6 +54,9 @@ #include <string.h> +STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = + STAILQ_HEAD_INITIALIZER(g_msys_pool_list); + int os_mqueue_init(struct os_mqueue *mq, void *arg) { @@ -84,7 +87,11 @@ os_mqueue_get(struct os_mqueue *mq) } OS_EXIT_CRITICAL(sr); - m = OS_MBUF_PKTHDR_TO_MBUF(mp); + if (mp) { + m = OS_MBUF_PKTHDR_TO_MBUF(mp); + } else { + m = NULL; + } return (m); } @@ -117,6 +124,83 @@ err: return (rc); } +int +os_msys_register(struct os_mbuf_pool *new_pool) +{ + struct os_mbuf_pool *pool; + + pool = NULL; + STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { + if (new_pool->omp_databuf_len > pool->omp_databuf_len) { + break; + } + } + + if (pool) { + STAILQ_INSERT_AFTER(&g_msys_pool_list, pool, new_pool, omp_next); + } else { + STAILQ_INSERT_TAIL(&g_msys_pool_list, new_pool, omp_next); + } + + return (0); +} + +static struct os_mbuf_pool * +_os_msys_find_pool(uint16_t dsize) +{ + struct os_mbuf_pool *pool; + + pool = NULL; + STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { + if (dsize <= pool->omp_databuf_len) { + break; + } + } + + if (!pool) { + pool = STAILQ_LAST(&g_msys_pool_list, os_mbuf_pool, omp_next); + } + + return (pool); +} + + + +struct os_mbuf * +os_msys_get(uint16_t dsize, uint16_t leadingspace) +{ + struct os_mbuf *m; + struct os_mbuf_pool *pool; + + pool = _os_msys_find_pool(dsize); + if (!pool) { + goto err; + } + + m = os_mbuf_get(pool, leadingspace); + return (m); +err: + return (NULL); +} + + +struct os_mbuf * +os_msys_get_pkthdr(uint16_t dsize, uint16_t pkthdr_len) +{ + struct os_mbuf *m; + struct os_mbuf_pool *pool; + + pool = _os_msys_find_pool(dsize + pkthdr_len); + if (!pool) { + goto err; + } + + m = os_mbuf_get_pkthdr(pool, pkthdr_len); + return (m); +err: + return (NULL); +} + /** * Initialize a pool of mbufs. @@ -161,6 +245,7 @@ os_mbuf_get(struct os_mbuf_pool *omp, uint16_t leadingspace) SLIST_NEXT(om, om_next) = NULL; om->om_flags = 0; + om->om_pkthdr_len = 0; om->om_len = 0; om->om_data = (&om->om_databuf[0] + leadingspace); om->om_omp = omp; @@ -204,9 +289,11 @@ os_mbuf_free(struct os_mbuf *om) { int rc; - rc = os_memblock_put(om->om_omp->omp_pool, om); - if (rc != 0) { - goto err; + if (om->om_omp != NULL) { + rc = os_memblock_put(om->om_omp->omp_pool, om); + if (rc != 0) { + goto err; + } } return (0); @@ -829,8 +916,6 @@ os_mbuf_extend(struct os_mbuf *om, uint16_t len) return data; } -#if 0 - /** * Rearrange a mbuf chain so that len bytes are contiguous, * and in the data area of an mbuf (so that OS_MBUF_DATA() will @@ -851,40 +936,58 @@ struct os_mbuf * os_mbuf_pullup(struct os_mbuf *om, uint16_t len) { struct os_mbuf_pool *omp; - struct os_mbuf *newm; + struct os_mbuf *next; + struct os_mbuf *om2; + int count; + int space; omp = om->om_omp; - if (len > omp->omp_databuf_len) { - goto err; - } - - /* Is 'n' bytes already contiguous? */ - if (((uint8_t *) &om->om_databuf[0] + omp->omp_databuf_len) - - OS_MBUF_DATA(om, uint8_t *) >= len) { - newm = om; - goto done; - } - - /* Nope, OK. Allocate a new buffer, and then go through and copy 'n' - * bytes into that buffer. + /* + * If first mbuf has no cluster, and has room for len bytes + * without shifting current data, pullup into it, + * otherwise allocate a new mbuf to prepend to the chain. */ - newm = os_mbuf_get(omp, 0); - if (!newm) { - goto err; - } - - written = 0; - while (written < len - - -done: - return (newm); -err: - if (om) { - os_mbuf_free_chain(om); + if (om->om_len >= len) { + return (om); } - + if (om->om_len + OS_MBUF_TRAILINGSPACE(om) >= len && + SLIST_NEXT(om, om_next)) { + om2 = om; + om = SLIST_NEXT(om, om_next); + len -= om2->om_len; + } else { + if (len > omp->omp_databuf_len - om->om_pkthdr_len) + goto bad; + om2 = os_mbuf_get(omp, 0); + if (om2 == NULL) + goto bad; + if (OS_MBUF_IS_PKTHDR(om)) + _os_mbuf_copypkthdr(om2, om); + } + space = OS_MBUF_TRAILINGSPACE(om2); + do { + count = min(min(len, space), om->om_len); + memcpy(om2->om_data + om2->om_len, om->om_data, count); + len -= count; + om2->om_len += count; + om->om_len -= count; + space -= count; + if (om->om_len) + om->om_data += count; + else { + next = SLIST_NEXT(om, om_next); + os_mbuf_free(om); + om = next; + } + } while (len > 0 && om); + if (len > 0) { + os_mbuf_free(om2); + goto bad; + } + SLIST_NEXT(om2, om_next) = om; + return (om2); +bad: + os_mbuf_free_chain(om); return (NULL); } -#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/os_mutex.c ---------------------------------------------------------------------- diff --git a/libs/os/src/os_mutex.c b/libs/os/src/os_mutex.c index 3ad3151..0965be8 100644 --- a/libs/os/src/os_mutex.c +++ b/libs/os/src/os_mutex.c @@ -98,11 +98,7 @@ os_mutex_release(struct os_mutex *mu) rdy = SLIST_FIRST(&mu->mu_head); if (rdy) { /* There is one waiting. Wake it up */ - assert(rdy->t_mutex); - rdy->t_mutex = NULL; - - SLIST_REMOVE_HEAD(&mu->mu_head, t_obj_list); - SLIST_NEXT(rdy, t_obj_list) = NULL; + assert(rdy->t_obj); os_sched_wakeup(rdy); /* Set mutex internals */ @@ -214,13 +210,17 @@ os_mutex_pend(struct os_mutex *mu, uint32_t timeout) } /* Set mutex pointer in task */ - current->t_mutex = mu; + current->t_obj = mu; + current->t_flags |= OS_TASK_FLAG_MUTEX_WAIT; os_sched_sleep(current, timeout); - OS_EXIT_CRITICAL(sr); os_sched(NULL, 0); + OS_ENTER_CRITICAL(sr); + current->t_flags &= ~OS_TASK_FLAG_MUTEX_WAIT; + OS_EXIT_CRITICAL(sr); + /* If we are owner we did not time out. */ if (mu->mu_owner == current) { rc = OS_OK; @@ -276,10 +276,7 @@ os_mutex_delete(struct os_mutex *mu) /* Now, go through all the tasks waiting on the mutex */ while (!SLIST_EMPTY(&mu->mu_head)) { rdy = SLIST_FIRST(&mu->mu_head); - assert(rdy->t_mutex); - rdy->t_mutex = NULL; - SLIST_REMOVE_HEAD(&mu->mu_head, t_obj_list); - SLIST_NEXT(rdy, t_obj_list) = NULL; + assert(rdy->t_obj); os_sched_wakeup(rdy); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/os_sched.c ---------------------------------------------------------------------- diff --git a/libs/os/src/os_sched.c b/libs/os/src/os_sched.c index 944f0f6..f1c03c6 100644 --- a/libs/os/src/os_sched.c +++ b/libs/os/src/os_sched.c @@ -243,12 +243,17 @@ os_sched_sleep(struct os_task *t, os_time_t nticks) int os_sched_wakeup(struct os_task *t) { - /* Remove self from mutex list if waiting on one */ - if (t->t_mutex) { - assert(!SLIST_EMPTY(&t->t_mutex->mu_head)); - SLIST_REMOVE(&t->t_mutex->mu_head, t, os_task, t_obj_list); + struct os_task_obj *os_obj; + + assert(t->t_state == OS_TASK_SLEEP); + + /* Remove self from object list if waiting on one */ + if (t->t_obj) { + os_obj = (struct os_task_obj *)t->t_obj; + assert(!SLIST_EMPTY(&os_obj->obj_head)); + SLIST_REMOVE(&os_obj->obj_head, t, os_task, t_obj_list); SLIST_NEXT(t, t_obj_list) = NULL; - t->t_mutex = NULL; + t->t_obj = NULL; } /* Remove task from sleep list */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/os_sem.c ---------------------------------------------------------------------- diff --git a/libs/os/src/os_sem.c b/libs/os/src/os_sem.c index d3b395c..84464d3 100644 --- a/libs/os/src/os_sem.c +++ b/libs/os/src/os_sem.c @@ -86,12 +86,8 @@ os_sem_release(struct os_sem *sem) /* Check if tasks are waiting for the semaphore */ rdy = SLIST_FIRST(&sem->sem_head); if (rdy) { - /* Clear flag that we are waiting on the semaphore */ + /* Clear flag that we are waiting on the semaphore; wake up task */ rdy->t_flags &= ~OS_TASK_FLAG_SEM_WAIT; - - /* There is one waiting. Wake it up */ - SLIST_REMOVE_HEAD(&sem->sem_head, t_obj_list); - SLIST_NEXT(rdy, t_obj_list) = NULL; os_sched_wakeup(rdy); /* Schedule if waiting task higher priority */ @@ -169,6 +165,7 @@ os_sem_pend(struct os_sem *sem, uint32_t timeout) rc = OS_OK; /* Link current task to tasks waiting for semaphore */ + current->t_obj = sem; current->t_flags |= OS_TASK_FLAG_SEM_WAIT; last = NULL; if (!SLIST_EMPTY(&sem->sem_head)) { @@ -258,9 +255,7 @@ os_sem_delete(struct os_sem *sem) /* Now, go through all the tasks waiting on the semaphore */ while (rdy != NULL) { - SLIST_REMOVE_HEAD(&sem->sem_head, t_obj_list); - SLIST_NEXT(rdy, t_obj_list) = NULL; - os_sched_wakeup(rdy); + os_sched_wakeup(rdy); rdy = SLIST_FIRST(&sem->sem_head); } } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/test/mbuf_test.c ---------------------------------------------------------------------- diff --git a/libs/os/src/test/mbuf_test.c b/libs/os/src/test/mbuf_test.c index 8652494..fb7c4de 100644 --- a/libs/os/src/test/mbuf_test.c +++ b/libs/os/src/test/mbuf_test.c @@ -50,6 +50,8 @@ TEST_CASE(os_mbuf_test_case_1) struct os_mbuf *m; int rc; + os_mbuf_test_setup(); + m = os_mbuf_get(&os_mbuf_pool, 0); TEST_ASSERT_FATAL(m != NULL, "Error allocating mbuf"); @@ -64,6 +66,8 @@ TEST_CASE(os_mbuf_test_case_2) struct os_mbuf *dup; int rc; + os_mbuf_test_setup(); + /* Test first allocating and duplicating a single mbuf */ m = os_mbuf_get(&os_mbuf_pool, 0); TEST_ASSERT_FATAL(m != NULL, "Error allocating mbuf"); @@ -106,6 +110,8 @@ TEST_CASE(os_mbuf_test_case_3) uint8_t databuf[] = {0xa, 0xb, 0xc, 0xd}; uint8_t cmpbuf[] = {0xff, 0xff, 0xff, 0xff}; + os_mbuf_test_setup(); + m = os_mbuf_get(&os_mbuf_pool, 0); TEST_ASSERT_FATAL(m != NULL, "Error allocating mbuf"); @@ -121,15 +127,98 @@ TEST_CASE(os_mbuf_test_case_3) "Databuf doesn't match cmpbuf"); } -TEST_SUITE(os_mbuf_test_case_4) +static void +os_mbuf_test_misc_assert_contiguous(struct os_mbuf *om, void *data, int len) { + TEST_ASSERT_FATAL(om != NULL); + + if (OS_MBUF_IS_PKTHDR(om)) { + TEST_ASSERT(OS_MBUF_PKTLEN(om) == len); + } + TEST_ASSERT(om->om_len == len); + TEST_ASSERT(memcmp(om->om_data, data, len) == 0); } -TEST_SUITE(os_mbuf_test_suite) +TEST_CASE(os_mbuf_test_pullup) { + struct os_mbuf *om; + struct os_mbuf *om2; + uint8_t data[256]; + int rc; + int i; + os_mbuf_test_setup(); + for (i = 0; i < sizeof data; i++) { + data[i] = i; + } + + /*** Free when too much data is requested. */ + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om != NULL); + + om = os_mbuf_pullup(om, 1); + TEST_ASSERT(om == NULL); + + /*** No effect when all data is already at the start. */ + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om != NULL); + + rc = os_mbuf_append(om, data, 1); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_test_misc_assert_contiguous(om, data, 1); + + om = os_mbuf_pullup(om, 1); + os_mbuf_test_misc_assert_contiguous(om, data, 1); + + /*** Spread data across four mbufs. */ + om2 = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, data + 1, 1); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + om2 = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, data + 2, 1); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + om2 = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, data + 3, 1); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + TEST_ASSERT_FATAL(OS_MBUF_PKTLEN(om) == 4); + + om = os_mbuf_pullup(om, 4); + os_mbuf_test_misc_assert_contiguous(om, data, 4); + + os_mbuf_free_chain(om); + + /*** Require an allocation. */ + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om != NULL); + + om->om_data += 100; + rc = os_mbuf_append(om, data, 100); + TEST_ASSERT_FATAL(rc == 0); + + om2 = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, data + 100, 100); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + om = os_mbuf_pullup(om, 200); + os_mbuf_test_misc_assert_contiguous(om, data, 200); +} + +TEST_SUITE(os_mbuf_test_suite) +{ os_mbuf_test_case_1(); os_mbuf_test_case_2(); os_mbuf_test_case_3(); + os_mbuf_test_pullup(); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/test/mutex_test.c ---------------------------------------------------------------------- diff --git a/libs/os/src/test/mutex_test.c b/libs/os/src/test/mutex_test.c index a861dbb..7d9a08c 100644 --- a/libs/os/src/test/mutex_test.c +++ b/libs/os/src/test/mutex_test.c @@ -178,6 +178,14 @@ mutex_test2_task14_handler(void *arg) g_task14_val = 1; os_time_delay(100); + /* + * Task17 should have its mutex wait flag set; at least the first time + * through! + */ + if (iters == 0) { + TEST_ASSERT(task17.t_flags & OS_TASK_FLAG_MUTEX_WAIT); + } + if (g_mutex_test == 4) { os_mutex_delete(&g_mutex1); os_time_delay(150); @@ -303,6 +311,7 @@ task17_handler(void *arg) err = os_mutex_pend(&g_mutex1, 10); } else { err = os_mutex_pend(&g_mutex1, 10000); + TEST_ASSERT((t->t_flags & OS_TASK_FLAG_MUTEX_WAIT) == 0); } if (g_mutex_test == 4 || g_mutex_test == 5) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/os/src/test/sem_test.c ---------------------------------------------------------------------- diff --git a/libs/os/src/test/sem_test.c b/libs/os/src/test/sem_test.c index 75b2e40..fbaf82b 100644 --- a/libs/os/src/test/sem_test.c +++ b/libs/os/src/test/sem_test.c @@ -95,7 +95,7 @@ sem_test_pend_release_loop(int delay, int timeout, int itvl) while (1) { err = os_sem_pend(&g_sem1, timeout); - TEST_ASSERT(err == OS_OK); + TEST_ASSERT((err == OS_OK) || (err == OS_TIMEOUT)); err = os_sem_release(&g_sem1); TEST_ASSERT(err == OS_OK); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/util/include/util/base64.h ---------------------------------------------------------------------- diff --git a/libs/util/include/util/base64.h b/libs/util/include/util/base64.h new file mode 100644 index 0000000..fff40fd --- /dev/null +++ b/libs/util/include/util/base64.h @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2015 Runtime 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 __UTIL_BASE64_H +#define __UTIL_BASE64_H + +#include <stdint.h> + +int base64_encode(const void *, int, char *, uint8_t); +int base64_decode(const char *, void *buf); + +#define BASE64_ENCODE_SIZE(__size) (((__size) * (4 / 3)) + 4) + +#endif /* __UTIL_BASE64_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/util/src/base64.c ---------------------------------------------------------------------- diff --git a/libs/util/src/base64.c b/libs/util/src/base64.c new file mode 100644 index 0000000..3b07362 --- /dev/null +++ b/libs/util/src/base64.c @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2015 Runtime 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. + */ + +/* + * This file is based on roken from the FreeBSD source. It has been modified + * to not use malloc() and instead expect static buffers, and tabs have been + * replaced with spaces. Also, instead of strlen() on the resulting string, + * pointer arithmitic is done, as p represents the end of the buffer. + */ + +/* + * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <string.h> + +#include <util/base64.h> + +static const char base64_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static int +pos(char c) +{ + const char *p; + for (p = base64_chars; *p; p++) + if (*p == c) + return p - base64_chars; + return -1; +} + +int +base64_encode(const void *data, int size, char *s, uint8_t should_pad) +{ + char *p; + int i; + int c; + const unsigned char *q; + char *last; + int diff; + + p = s; + + q = (const unsigned char *) data; + last = NULL; + i = 0; + while (i < size) { + c = q[i++]; + c *= 256; + if (i < size) + c += q[i]; + i++; + c *= 256; + if (i < size) + c += q[i]; + i++; + p[0] = base64_chars[(c & 0x00fc0000) >> 18]; + p[1] = base64_chars[(c & 0x0003f000) >> 12]; + p[2] = base64_chars[(c & 0x00000fc0) >> 6]; + p[3] = base64_chars[(c & 0x0000003f) >> 0]; + last = p; + p += 4; + } + + if (last) { + diff = i - size; + if (diff > 0) { + if (should_pad) { + memset(last + (4 - diff), '=', diff); + } else { + p = last + (4 - diff); + } + } + } + + *p = 0; + + return (p - s); +} + +#define DECODE_ERROR -1 + +static unsigned int +token_decode(const char *token) +{ + int i; + unsigned int val = 0; + int marker = 0; + if (strlen(token) < 4) + return DECODE_ERROR; + for (i = 0; i < 4; i++) { + val *= 64; + if (token[i] == '=') + marker++; + else if (marker > 0) + return DECODE_ERROR; + else + val += pos(token[i]); + } + if (marker > 2) + return DECODE_ERROR; + return (marker << 24) | val; +} + +int +base64_decode(const char *str, void *data) +{ + const char *p; + unsigned char *q; + + q = data; + for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) { + unsigned int val = token_decode(p); + unsigned int marker = (val >> 24) & 0xff; + if (val == DECODE_ERROR) + return -1; + *q++ = (val >> 16) & 0xff; + if (marker < 2) + *q++ = (val >> 8) & 0xff; + if (marker < 1) + *q++ = val & 0xff; + } + return q - (unsigned char *) data; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/util/src/flash_map.c ---------------------------------------------------------------------- diff --git a/libs/util/src/flash_map.c b/libs/util/src/flash_map.c index 28f26c9..81d0f22 100644 --- a/libs/util/src/flash_map.c +++ b/libs/util/src/flash_map.c @@ -82,36 +82,69 @@ flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret) } #ifdef NFFS_PRESENT +/* + * Turn flash region into a set of areas for NFFS use. + * + * Limit the number of regions we return to be less than *cnt. + * If sector count within region exceeds that, collect multiple sectors + * to a region. + */ int flash_area_to_nffs_desc(int idx, int *cnt, struct nffs_area_desc *nad) { - int i; + int i, j; const struct hal_flash *hf; const struct flash_area *fa; + int max_cnt, move_on; + int first_idx, last_idx; uint32_t start, size; + uint32_t min_size; if (!flash_map || idx >= flash_map_entries) { return -1; } + first_idx = last_idx = -1; + max_cnt = *cnt; *cnt = 0; + fa = &flash_map[idx]; hf = bsp_flash_dev(fa->fa_flash_id); for (i = 0; i < hf->hf_sector_cnt; i++) { hf->hf_itf->hff_sector_info(i, &start, &size); if (start >= fa->fa_off && start < fa->fa_off + fa->fa_size) { - if (nad) { - nad->nad_flash_id = fa->fa_flash_id; - nad->nad_offset = start; - nad->nad_length = size; - nad++; + if (first_idx == -1) { + first_idx = i; } + last_idx = i; *cnt = *cnt + 1; } } - if (nad) { - memset(nad, 0, sizeof(*nad)); + if (*cnt > max_cnt) { + min_size = fa->fa_size / max_cnt; + } else { + min_size = 0; + } + *cnt = 0; + + move_on = 1; + for (i = first_idx, j = 0; i < last_idx + 1; i++) { + hf->hf_itf->hff_sector_info(i, &start, &size); + if (move_on) { + nad[j].nad_flash_id = fa->fa_flash_id; + nad[j].nad_offset = start; + nad[j].nad_length = size; + *cnt = *cnt + 1; + move_on = 0; + } else { + nad[j].nad_length += size; + } + if (nad[j].nad_length >= min_size) { + j++; + move_on = 1; + } } + nad[*cnt].nad_length = 0; return 0; } #endif /* NFFS_PRESENT */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/f42a66b1/libs/util/src/stats.c ---------------------------------------------------------------------- diff --git a/libs/util/src/stats.c b/libs/util/src/stats.c index 0d2eb36..e61d785 100644 --- a/libs/util/src/stats.c +++ b/libs/util/src/stats.c @@ -43,6 +43,7 @@ uint8_t stats_shell_registered; struct shell_cmd shell_stats_cmd; #endif + #ifdef SHELL_PRESENT static void @@ -130,6 +131,7 @@ done: #endif + int stats_module_init(void) { @@ -141,6 +143,7 @@ stats_module_init(void) } #endif + rc = stats_init(STATS_HDR(stats), STATS_SIZE_INIT_PARMS(stats, STATS_SIZE_32), STATS_NAME_INIT_PARMS(stats)); if (rc != 0) {
