/*
|
* Licensed to the Apache Software Foundation (ASF) under one
|
* or more contributor license agreements. See the NOTICE file
|
* distributed with this work for additional information
|
* regarding copyright ownership. The ASF licenses this file
|
* to you 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 <assert.h>
|
#include "os/os.h"
|
#include "mem/mem.h"
|
#include "sysinit/sysinit.h"
|
#include "os/panchip_mempool.h"
|
|
#if OS_MSYS_SANITY_ENABLED
|
static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list =
|
STAILQ_HEAD_INITIALIZER(g_msys_pool_list);
|
#endif
|
|
#if MYNEWT_VAL(MSYS_1_BLOCK_COUNT) > 0
|
#define SYSINIT_MSYS_1_MEMBLOCK_SIZE \
|
OS_ALIGN(MYNEWT_VAL(MSYS_1_BLOCK_SIZE), 4)
|
#define SYSINIT_MSYS_1_MEMPOOL_SIZE \
|
OS_MEMPOOL_SIZE(MYNEWT_VAL(MSYS_1_BLOCK_COUNT), \
|
SYSINIT_MSYS_1_MEMBLOCK_SIZE)
|
|
#ifdef IP_101x
|
static os_membuf_t *os_msys_1_data;
|
#else
|
static os_membuf_t os_msys_1_data[SYSINIT_MSYS_1_MEMPOOL_SIZE];
|
#endif
|
static struct os_mbuf_pool os_msys_1_mbuf_pool;
|
static struct os_mempool os_msys_1_mempool;
|
#endif
|
|
#if MYNEWT_VAL(MSYS_2_BLOCK_COUNT) > 0
|
#define SYSINIT_MSYS_2_MEMBLOCK_SIZE \
|
OS_ALIGN(MYNEWT_VAL(MSYS_2_BLOCK_SIZE), 4)
|
#define SYSINIT_MSYS_2_MEMPOOL_SIZE \
|
OS_MEMPOOL_SIZE(MYNEWT_VAL(MSYS_2_BLOCK_COUNT), \
|
SYSINIT_MSYS_2_MEMBLOCK_SIZE)
|
static os_membuf_t os_msys_2_data[SYSINIT_MSYS_2_MEMPOOL_SIZE];
|
static struct os_mbuf_pool os_msys_2_mbuf_pool;
|
static struct os_mempool os_msys_2_mempool;
|
#endif
|
|
#define OS_MSYS_SANITY_ENABLED \
|
(MYNEWT_VAL(MSYS_1_SANITY_MIN_COUNT) > 0 || \
|
MYNEWT_VAL(MSYS_2_SANITY_MIN_COUNT) > 0)
|
|
#if OS_MSYS_SANITY_ENABLED
|
static struct os_sanity_check os_msys_sc;
|
#endif
|
|
#if OS_MSYS_SANITY_ENABLED
|
|
/**
|
* Retrieves the minimum safe buffer count for an msys pool. That is, the
|
* lowest a pool's buffer count can be without causing the sanity check to
|
* fail.
|
*
|
* @param idx The index of the msys pool to query.
|
*
|
* @return The msys pool's minimum safe buffer count.
|
*/
|
static int
|
os_msys_sanity_min_count(int idx)
|
{
|
switch (idx) {
|
case 0:
|
return MYNEWT_VAL(MSYS_1_SANITY_MIN_COUNT);
|
|
case 1:
|
return MYNEWT_VAL(MSYS_2_SANITY_MIN_COUNT);
|
|
default:
|
assert(0);
|
return 0;
|
}
|
}
|
|
static int
|
os_msys_sanity(struct os_sanity_check *sc, void *arg)
|
{
|
const struct os_mbuf_pool *omp;
|
int min_count;
|
int idx;
|
|
idx = 0;
|
STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) {
|
min_count = os_msys_sanity_min_count(idx);
|
if (omp->omp_pool->mp_num_free < min_count) {
|
return OS_ENOMEM;
|
}
|
|
idx++;
|
}
|
|
return 0;
|
}
|
#endif
|
|
static void
|
os_msys_init_once(void *data, struct os_mempool *mempool,
|
struct os_mbuf_pool *mbuf_pool,
|
int block_count, int block_size, char *name)
|
{
|
int rc;
|
|
rc = mem_init_mbuf_pool(data, mempool, mbuf_pool, block_count, block_size,
|
name);
|
SYSINIT_PANIC_ASSERT(rc == 0);
|
|
rc = os_msys_register(mbuf_pool);
|
SYSINIT_PANIC_ASSERT(rc == 0);
|
}
|
|
void
|
os_msys_init(void)
|
{
|
int rc;
|
#ifdef IP_101x
|
os_msys_1_data = panchip_mem_get(SYSINIT_MSYS_1_MEMPOOL_SIZE * 4, 4);
|
#endif
|
os_msys_reset();
|
|
(void)os_msys_init_once;
|
(void)rc;
|
|
#if MYNEWT_VAL(MSYS_1_BLOCK_COUNT) > 0
|
os_msys_init_once(os_msys_1_data,
|
&os_msys_1_mempool,
|
&os_msys_1_mbuf_pool,
|
MYNEWT_VAL(MSYS_1_BLOCK_COUNT),
|
SYSINIT_MSYS_1_MEMBLOCK_SIZE,
|
"msys_1");
|
#endif
|
|
#if MYNEWT_VAL(MSYS_2_BLOCK_COUNT) > 0
|
os_msys_init_once(os_msys_2_data,
|
&os_msys_2_mempool,
|
&os_msys_2_mbuf_pool,
|
MYNEWT_VAL(MSYS_2_BLOCK_COUNT),
|
SYSINIT_MSYS_2_MEMBLOCK_SIZE,
|
"msys_2");
|
#endif
|
|
#if OS_MSYS_SANITY_ENABLED
|
os_msys_sc.sc_func = os_msys_sanity;
|
os_msys_sc.sc_checkin_itvl =
|
OS_TICKS_PER_SEC * MYNEWT_VAL(MSYS_SANITY_TIMEOUT) / 1000;
|
rc = os_sanity_check_register(&os_msys_sc);
|
SYSINIT_PANIC_ASSERT(rc == 0);
|
#endif
|
}
|