SNMP: Update threadsync not to use mem_malloc - memory can be instantiated statically since it is only needed once per threadsync instance

This commit is contained in:
Dirk Ziegelmeier 2016-02-02 22:31:59 +01:00
parent 8f6cfa8769
commit 28549e35fe
4 changed files with 61 additions and 70 deletions

View File

@ -97,7 +97,7 @@ snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg)
tcpip_callback_with_block(fn, arg, 1); tcpip_callback_with_block(fn, arg, 1);
} }
struct snmp_threadsync_locks snmp_mib2_lwip_locks; struct snmp_threadsync_instance snmp_mib2_lwip_locks;
#define SYNC_NODE_NAME(node_name) node_name ## _synced #define SYNC_NODE_NAME(node_name) node_name ## _synced
#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ #define CREATE_LWIP_SYNC_NODE(oid, node_name) \

View File

@ -33,35 +33,16 @@
#include "lwip/apps/snmp_threadsync.h" #include "lwip/apps/snmp_threadsync.h"
#include "lwip/apps/snmp_core.h" #include "lwip/apps/snmp_core.h"
#include "lwip/mem.h"
#include "lwip/sys.h" #include "lwip/sys.h"
#include <string.h> #include <string.h>
struct threadsync_data
{
union {
snmp_err_t u8;
u16_t u16;
} retval;
union {
const u32_t *root_oid;
void *value;
} arg1;
union {
u8_t root_oid_len;
u16_t len;
} arg2;
const struct snmp_threadsync_node *threadsync_node;
struct snmp_node_instance proxy_instance;
};
static void static void
call_synced_function(struct threadsync_data *call_data, snmp_threadsync_called_fn fn) call_synced_function(struct threadsync_data *call_data, snmp_threadsync_called_fn fn)
{ {
sys_mutex_lock(&call_data->threadsync_node->locks->sem_usage_mutex); sys_mutex_lock(&call_data->threadsync_node->instance->sem_usage_mutex);
call_data->threadsync_node->locks->sync_fn(fn, call_data); call_data->threadsync_node->instance->sync_fn(fn, call_data);
sys_sem_wait(&call_data->threadsync_node->locks->sem); sys_sem_wait(&call_data->threadsync_node->instance->sem);
sys_mutex_unlock(&call_data->threadsync_node->locks->sem_usage_mutex); sys_mutex_unlock(&call_data->threadsync_node->instance->sem_usage_mutex);
} }
static void static void
@ -71,7 +52,7 @@ threadsync_get_value_synced(void *ctx)
call_data->retval.u16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value); call_data->retval.u16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value);
sys_sem_signal(&call_data->threadsync_node->locks->sem); sys_sem_signal(&call_data->threadsync_node->instance->sem);
} }
static u16_t static u16_t
threadsync_get_value(struct snmp_node_instance* instance, void* value) threadsync_get_value(struct snmp_node_instance* instance, void* value)
@ -91,7 +72,7 @@ threadsync_set_test_synced(void *ctx)
call_data->retval.u8 = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); call_data->retval.u8 = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
sys_sem_signal(&call_data->threadsync_node->locks->sem); sys_sem_signal(&call_data->threadsync_node->instance->sem);
} }
static snmp_err_t static snmp_err_t
threadsync_set_test(struct snmp_node_instance* instance, u16_t len, void *value) threadsync_set_test(struct snmp_node_instance* instance, u16_t len, void *value)
@ -112,7 +93,7 @@ threadsync_set_value_synced(void *ctx)
call_data->retval.u8 = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); call_data->retval.u8 = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
sys_sem_signal(&call_data->threadsync_node->locks->sem); sys_sem_signal(&call_data->threadsync_node->instance->sem);
} }
static snmp_err_t static snmp_err_t
threadsync_set_value(struct snmp_node_instance* instance, u16_t len, void *value) threadsync_set_value(struct snmp_node_instance* instance, u16_t len, void *value)
@ -133,7 +114,7 @@ threadsync_release_instance_synced(void* ctx)
call_data->proxy_instance.release_instance(&call_data->proxy_instance); call_data->proxy_instance.release_instance(&call_data->proxy_instance);
sys_sem_signal(&call_data->threadsync_node->locks->sem); sys_sem_signal(&call_data->threadsync_node->instance->sem);
} }
static void static void
threadsync_release_instance(struct snmp_node_instance *instance) threadsync_release_instance(struct snmp_node_instance *instance)
@ -143,8 +124,6 @@ threadsync_release_instance(struct snmp_node_instance *instance)
if(call_data->proxy_instance.release_instance != NULL) { if(call_data->proxy_instance.release_instance != NULL) {
call_synced_function(call_data, threadsync_release_instance_synced); call_synced_function(call_data, threadsync_release_instance_synced);
} }
mem_free(call_data);
} }
static void static void
@ -155,7 +134,7 @@ get_instance_synced(void* ctx)
call_data->retval.u8 = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); call_data->retval.u8 = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance);
sys_sem_signal(&call_data->threadsync_node->locks->sem); sys_sem_signal(&call_data->threadsync_node->instance->sem);
} }
static void static void
@ -166,51 +145,43 @@ get_next_instance_synced(void* ctx)
call_data->retval.u8 = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); call_data->retval.u8 = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance);
sys_sem_signal(&call_data->threadsync_node->locks->sem); sys_sem_signal(&call_data->threadsync_node->instance->sem);
} }
static snmp_err_t static snmp_err_t
do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance, snmp_threadsync_called_fn fn) do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance, snmp_threadsync_called_fn fn)
{ {
const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node*)instance->node; const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node*)instance->node;
struct threadsync_data *call_data; struct threadsync_data *call_data = &threadsync_node->instance->data;
if(threadsync_node->node.node.oid != threadsync_node->target->node.oid) { if(threadsync_node->node.node.oid != threadsync_node->target->node.oid) {
LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID")); LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID"));
return SNMP_ERR_NOSUCHINSTANCE; return SNMP_ERR_NOSUCHINSTANCE;
} }
call_data = (struct threadsync_data*)mem_malloc(sizeof(struct threadsync_data)); memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance));
if(call_data != NULL) {
memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance));
instance->reference.ptr = call_data; instance->reference.ptr = call_data;
snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len); snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len);
call_data->proxy_instance.node = &threadsync_node->target->node; call_data->proxy_instance.node = &threadsync_node->target->node;
call_data->threadsync_node = threadsync_node; call_data->threadsync_node = threadsync_node;
call_data->arg1.root_oid = root_oid; call_data->arg1.root_oid = root_oid;
call_data->arg2.root_oid_len = root_oid_len; call_data->arg2.root_oid_len = root_oid_len;
call_synced_function(call_data, fn); call_synced_function(call_data, fn);
if(call_data->retval.u8 == SNMP_ERR_NOERROR) { if(call_data->retval.u8 == SNMP_ERR_NOERROR) {
instance->access = call_data->proxy_instance.access; instance->access = call_data->proxy_instance.access;
instance->asn1_type = call_data->proxy_instance.asn1_type; instance->asn1_type = call_data->proxy_instance.asn1_type;
instance->release_instance = threadsync_release_instance; instance->release_instance = threadsync_release_instance;
instance->get_value = (call_data->proxy_instance.get_value != NULL)? threadsync_get_value : NULL; instance->get_value = (call_data->proxy_instance.get_value != NULL)? threadsync_get_value : NULL;
instance->set_value = (call_data->proxy_instance.set_value != NULL)? threadsync_set_value : NULL; instance->set_value = (call_data->proxy_instance.set_value != NULL)? threadsync_set_value : NULL;
instance->set_test = (call_data->proxy_instance.set_test != NULL)? threadsync_set_test : NULL; instance->set_test = (call_data->proxy_instance.set_test != NULL)? threadsync_set_test : NULL;
snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len); snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len);
} else {
mem_free(call_data);
}
return call_data->retval.u8;
} else {
LWIP_DEBUGF(SNMP_DEBUG, ("Out of memory"));
return SNMP_ERR_NOSUCHINSTANCE;
} }
return call_data->retval.u8;
} }
snmp_err_t snmp_err_t
@ -225,11 +196,11 @@ snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, stru
return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced); return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced);
} }
void snmp_threadsync_init(struct snmp_threadsync_locks *locks, snmp_threadsync_synchronizer_fn sync_fn) void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn)
{ {
sys_mutex_new(&locks->sem_usage_mutex); sys_mutex_new(&instance->sem_usage_mutex);
sys_sem_new(&locks->sem, 0); sys_sem_new(&instance->sem, 0);
locks->sync_fn = sync_fn; instance->sync_fn = sync_fn;
} }
#endif /* LWIP_SNMP */ #endif /* LWIP_SNMP */

View File

@ -54,7 +54,7 @@ extern const struct snmp_mib mib2;
#if SNMP_USE_NETCONN #if SNMP_USE_NETCONN
#include "lwip/apps/snmp_threadsync.h" #include "lwip/apps/snmp_threadsync.h"
void snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg); void snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg);
extern struct snmp_threadsync_locks snmp_mib2_lwip_locks; extern struct snmp_threadsync_instance snmp_mib2_lwip_locks;
#endif #endif
#ifndef SNMP_SYSSERVICES #ifndef SNMP_SYSSERVICES

View File

@ -47,20 +47,40 @@ extern "C" {
typedef void (*snmp_threadsync_called_fn)(void* arg); typedef void (*snmp_threadsync_called_fn)(void* arg);
typedef void (*snmp_threadsync_synchronizer_fn)(snmp_threadsync_called_fn fn, void* arg); typedef void (*snmp_threadsync_synchronizer_fn)(snmp_threadsync_called_fn fn, void* arg);
struct snmp_threadsync_locks
struct threadsync_data
{
union {
snmp_err_t u8;
u16_t u16;
} retval;
union {
const u32_t *root_oid;
void *value;
} arg1;
union {
u8_t root_oid_len;
u16_t len;
} arg2;
const struct snmp_threadsync_node *threadsync_node;
struct snmp_node_instance proxy_instance;
};
struct snmp_threadsync_instance
{ {
sys_sem_t sem; sys_sem_t sem;
sys_mutex_t sem_usage_mutex; sys_mutex_t sem_usage_mutex;
snmp_threadsync_synchronizer_fn sync_fn; snmp_threadsync_synchronizer_fn sync_fn;
struct threadsync_data data;
}; };
/* thread sync node */ /* thread sync node */
struct snmp_threadsync_node struct snmp_threadsync_node
{ {
/* inherited "base class" members */ /* inherited "base class" members */
struct snmp_leaf_node node; struct snmp_leaf_node node;
const struct snmp_leaf_node *target; const struct snmp_leaf_node *target;
struct snmp_threadsync_locks *locks; struct snmp_threadsync_instance *instance;
}; };
snmp_err_t snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); snmp_err_t snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
@ -73,7 +93,7 @@ snmp_err_t snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oi
(target), \ (target), \
(locks) } (locks) }
void snmp_threadsync_init(struct snmp_threadsync_locks *locks, snmp_threadsync_synchronizer_fn sync_fn); void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn);
#endif /* LWIP_SNMP */ #endif /* LWIP_SNMP */