[sr-dev] git:master: modules/ims_qos: memory optimisation

Richard Good richard.good at smilecoms.com
Mon Oct 28 13:44:09 CET 2013


Module: sip-router
Branch: master
Commit: b5638f712711deb8413d7e585369adf8f4a421ee
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b5638f712711deb8413d7e585369adf8f4a421ee

Author: Richard Good <richard.good at smilecoms.com>
Committer: Richard Good <richard.good at smilecoms.com>
Date:   Mon Oct 28 14:41:22 2013 +0200

modules/ims_qos: memory optimisation
	Fixed pkg memory allocation for framed IP AVP and flow buffer AVP
	Instead of repeatedly alloc'ing and free'ing pkg memory we allocate once and re-use
	Results in better pkg memory overhead

---

 modules/ims_qos/rx_avp.c |  101 +++++++++++++++++++++++++++-------------------
 1 files changed, 59 insertions(+), 42 deletions(-)

diff --git a/modules/ims_qos/rx_avp.c b/modules/ims_qos/rx_avp.c
index d628192..65c8a43 100644
--- a/modules/ims_qos/rx_avp.c
+++ b/modules/ims_qos/rx_avp.c
@@ -156,9 +156,12 @@ static inline str rx_get_avp(AAAMessage *msg, int avp_code, int vendor_id,
  * 	see http://beej.us/guide/bgnet/output/html/multipage/inet_ntopman.html
  * 	http://beej.us/guide/bgnet/output/html/multipage/sockaddr_inman.html
  */
+
+static unsigned int ip_buflen = 0;
+static char* ip_buf = 0;
+
 int rx_add_framed_ip_avp(AAA_AVP_LIST * list, str ip, uint16_t version) {
     ip_address_prefix ip_adr;
-    char* ip_pkg = 0;
     int ret = 0;
 
     if (ip.len < 0) return 0;
@@ -169,28 +172,36 @@ int rx_add_framed_ip_avp(AAA_AVP_LIST * list, str ip, uint16_t version) {
         if (ip.len > INET6_ADDRSTRLEN)
             goto error;
     }
-    ip_pkg = (char*) pkg_malloc((ip.len + 1) * sizeof (char));
-    if (!ip_pkg) {
-        LM_ERR("PCC_create_framed_ip_avp: could not allocate %i from pkg\n", ip.len + 1);
-        goto error;
+    int len = ip.len + 1;
+    if (!ip_buf || ip_buflen < len) {
+        if (ip_buf)
+                pkg_free(ip_buf);
+        ip_buf = (char*)pkg_malloc(len);
+        if (!ip_buf) {
+	    LM_ERR("rx_add_framed_ip_avp: out of memory \
+					    when allocating %i bytes in pkg\n", len);
+	    goto error;
+        }
+        ip_buflen = len;
     }
-    memcpy(ip_pkg, ip.s, ip.len);
-    ip_pkg[ip.len] = '\0';
-
+    memcpy(ip_buf, ip.s, ip.len);
+    ip_buf[ip.len] = '\0';
+    
     ip_adr.addr.ai_family = version;
 
     if (version == AF_INET) {
 
-        if (inet_pton(AF_INET, ip_pkg, &(ip_adr.addr.ip.v4.s_addr)) != 1) goto error;
+        if (inet_pton(AF_INET, ip_buf, &(ip_adr.addr.ip.v4.s_addr)) != 1) goto error;
         ret = cdp_avp->nasapp.add_Framed_IP_Address(list, ip_adr.addr);
     } else {
 
-        if (inet_pton(AF_INET6, ip_pkg, &(ip_adr.addr.ip.v6.s6_addr)) != 1) goto error;
+        if (inet_pton(AF_INET6, ip_buf, &(ip_adr.addr.ip.v6.s6_addr)) != 1) goto error;
         ret = cdp_avp->nasapp.add_Framed_IPv6_Prefix(list, ip_adr);
     }
 
+    //TODO: should free ip_buf in module shutdown....
+    
 error:
-    if (ip_pkg) pkg_free(ip_pkg);
     return ret;
 }
 
@@ -511,14 +522,17 @@ static char * permit_out_with_ports = "permit out %i from %.*s %u to %.*s %u";
 static char * permit_in_with_ports = "permit in %i from %.*s %u to %.*s %u";
 //static char * permit_in_with_ports = "permit in %i from %.*s %u to %.*s %u %s";
 
+static unsigned int flowdata_buflen = 0;
+static str flowdata_buf = {0,0};
+
 AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto,
         str *ipA, str *portA,
         str *ipB, str *portB) {
 
     str data;
     int len, len2;
-    str flow_data = {0, 0};
-    str flow_data2 = {0, 0};
+//    str flow_data = {0, 0};
+//    str flow_data2 = {0, 0};
     AAA_AVP *flow_description1 = 0, *flow_description2 = 0, *flow_number = 0;
     AAA_AVP *flow_usage = 0;
 
@@ -536,21 +550,16 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto,
     len = (permit_out.len + from_s.len + to_s.len + ipB->len + ipA->len + 4 +
             proto_len + portA->len + portB->len) * sizeof (char);
 
-    flow_data.s = (char*) pkg_malloc(len);
-    if (!flow_data.s) {
-        LM_ERR("PCC_create_media_component: out of memory \
-					when allocating %i bytes in pkg\n", len);
-        return NULL;
-    }
-
-    len2 = len - (permit_out.len - permit_in.len) * sizeof (char);
-    flow_data2.s = (char*) pkg_malloc(len2);
-    if (!flow_data2.s) {
-        LM_ERR("PCC_create_media_component: out of memory \
-					when allocating %i bytes in pkg\n", len);
-        pkg_free(flow_data.s);
-        flow_data.s = 0;
-        return NULL;
+    if (!flowdata_buf.s || flowdata_buflen < len) {
+        if (flowdata_buf.s)
+                pkg_free(flowdata_buf.s);
+        flowdata_buf.s = (char*)pkg_malloc(len);
+        if (!flowdata_buf.s) {
+                        LM_ERR("PCC_create_media_component: out of memory \
+                                                        when allocating %i bytes in pkg\n", len);
+                        return NULL ;
+        }
+        flowdata_buflen = len;
     }
 
     set_4bytes(x, number);
@@ -563,26 +572,39 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto,
     
     /*IMS Flow descriptions*/
     /*first flow is the receive flow*/
-    flow_data.len = snprintf(flow_data.s, len, permit_out_with_ports, proto_int,
+    flowdata_buf.len = snprintf(flowdata_buf.s, len, permit_out_with_ports, proto_int,
             ipB->len, ipB->s, intportB,
             ipA->len, ipA->s, intportA);
 
-    flow_data.len = strlen(flow_data.s);
+    flowdata_buf.len = strlen(flowdata_buf.s);
     flow_description1 = cdpb.AAACreateAVP(AVP_IMS_Flow_Description,
             AAA_AVP_FLAG_MANDATORY | AAA_AVP_FLAG_VENDOR_SPECIFIC,
-            IMS_vendor_id_3GPP, flow_data.s, flow_data.len,
+            IMS_vendor_id_3GPP, flowdata_buf.s, flowdata_buf.len,
             AVP_DUPLICATE_DATA);
     cdpb.AAAAddAVPToList(&list, flow_description1);
 
-    /*second flow*/
-    flow_data2.len = snprintf(flow_data2.s, len2, permit_in_with_ports, proto_int,
+        /*second flow*/
+    len2 = len - (permit_out.len - permit_in.len) * sizeof (char);
+        if (!flowdata_buf.s || flowdata_buflen <= len2) {
+                if (flowdata_buf.s)
+                        pkg_free(flowdata_buf.s);
+                flowdata_buf.s = (char*) pkg_malloc(len2);
+                if (!flowdata_buf.s) {
+                        LM_ERR("PCC_create_media_component: out of memory \
+                                                                when allocating %i bytes in pkg\n", len2);
+                        return NULL ;
+                }
+                flowdata_buflen = len2;
+        }
+
+    flowdata_buf.len = snprintf(flowdata_buf.s, len2, permit_in_with_ports, proto_int,
             ipA->len, ipA->s, intportA,
             ipB->len, ipB->s, intportB);
 
-    flow_data2.len = strlen(flow_data2.s);
+    flowdata_buf.len = strlen(flowdata_buf.s);
     flow_description2 = cdpb.AAACreateAVP(AVP_IMS_Flow_Description,
             AAA_AVP_FLAG_MANDATORY | AAA_AVP_FLAG_VENDOR_SPECIFIC,
-            IMS_vendor_id_3GPP, flow_data2.s, flow_data2.len,
+            IMS_vendor_id_3GPP, flowdata_buf.s, flowdata_buf.len,
             AVP_DUPLICATE_DATA);
     cdpb.AAAAddAVPToList(&list, flow_description2);
 
@@ -596,13 +618,9 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto,
     /*group all AVPS into one big.. and then free the small ones*/
 
     data = cdpb.AAAGroupAVPS(list);
-
-
     cdpb.AAAFreeAVPList(&list);
-    pkg_free(flow_data.s);
-    flow_data.s = 0;
-    pkg_free(flow_data2.s);
-    flow_data2.s = 0;
+
+    //TODO: should free the buffer for the flows in module shutdown....
 
     return (cdpb.AAACreateAVP(AVP_IMS_Media_Sub_Component,
             AAA_AVP_FLAG_MANDATORY | AAA_AVP_FLAG_VENDOR_SPECIFIC,
@@ -610,7 +628,6 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto,
             AVP_FREE_DATA));
 }
 
-
 //just for registration to signalling status much cut down MSC AVP
 //see 3GPP TS 29.214 4.4.5
 




More information about the sr-dev mailing list