On Friday 19 April 2013 12:36:15 Jan Friesse wrote:
> Jose,
> I was thinking about that problem a little deeper and what about
> implementing this:
> - Store buffer in cpg_inst (so alloc in cpg_initialize, free in
> cpg_finalize)
> - When dispatch is called, set variable in cpg_inst (something like
> is_in_dispatch) before callback and unset it after callback.
> - IF is_in_dispatch is set, allocate new buffer, else use buffer from
> cpg_inst
> 
> Basically, this should solve all problems with (in practice) no perf
> hit, because 99.9999% code doesn't reenter *_dispatch function, and make
> rest of 0.0001% code work correctly.

A tentative patch is attached, just for cpg for now. Freeing in finalize
is a bit tricky, as dispatch might still be running.

But this seems to be too much trouble when there is a decent workaround
(i.e., changing JVM's stack size with a simple command line parameter)
for my initial problem. So, I'm not pushing very hard for this
to get accepted.

-- 
Jose Orlando Pereira

diff --git a/lib/cpg.c b/lib/cpg.c
index b96df4e..cc589dc 100644
--- a/lib/cpg.c
+++ b/lib/cpg.c
@@ -54,6 +54,7 @@
 #include <qb/qbdefs.h>
 #include <qb/qbipcc.h>
 #include <qb/qblog.h>
+#include <qb/qbatomic.h>
 
 #include <corosync/hdb.h>
 #include <corosync/list.h>
@@ -72,6 +73,8 @@ struct cpg_inst {
        qb_ipcc_connection_t *c;
        int finalize;
        void *context;
+       char *dispatch_buf;
+       int in_dispatch;
        union {
                cpg_model_data_t model_data;
                cpg_model_v1_data_t model_v1_data;
@@ -169,6 +172,7 @@ cs_error_t cpg_model_initialize (
 {
        cs_error_t error;
        struct cpg_inst *cpg_inst;
+       char* dispatch_buf = NULL;
 
        if (model != CPG_MODEL_V1) {
                error = CS_ERR_INVALID_PARAM;
@@ -191,6 +195,13 @@ cs_error_t cpg_model_initialize (
                goto error_put_destroy;
        }
 
+       dispatch_buf = malloc(IPC_REQUEST_SIZE);
+       if (dispatch_buf == NULL) {
+               error = CS_ERR_NO_MEMORY;
+               goto error_destroy;
+       }
+       cpg_inst->dispatch_buf = dispatch_buf;
+
        if (model_data != NULL) {
                switch (model) {
                case CPG_MODEL_V1:
@@ -216,6 +227,7 @@ cs_error_t cpg_model_initialize (
 error_put_destroy:
        hdb_handle_put (&cpg_handle_t_db, *handle);
 error_destroy:
+       free(dispatch_buf);
        hdb_handle_destroy (&cpg_handle_t_db, *handle);
 error_no_destroy:
        return (error);
@@ -246,6 +258,13 @@ cs_error_t cpg_finalize (
        cpg_inst->finalize = 1;
 
        /*
+        * Free buffer only if dispatch is not currently using it
+        */
+       if (qb_atomic_int_compare_and_exchange(&cpg_inst->in_dispatch, 0, 1)) {
+               free(cpg_inst->dispatch_buf);
+       }
+
+       /*
         * Send service request
         */
        req_lib_cpg_finalize.header.size = sizeof (struct req_lib_cpg_finalize);
@@ -346,7 +365,8 @@ cs_error_t cpg_dispatch (
        struct cpg_ring_id ring_id;
        uint32_t totem_member_list[CPG_MEMBERS_MAX];
        int32_t errno_res;
-       char dispatch_buf[IPC_DISPATCH_SIZE];
+       char* dispatch_buf = NULL;
+       int owner = 0;
 
        error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, 
(void *)&cpg_inst));
        if (error != CS_OK) {
@@ -361,6 +381,17 @@ cs_error_t cpg_dispatch (
                timeout = 0;
        }
 
+       if (qb_atomic_int_compare_and_exchange(&cpg_inst->in_dispatch, 0, 1)) {
+               dispatch_buf = cpg_inst->dispatch_buf;
+       } else {
+               owner = 1;
+               dispatch_buf = malloc(IPC_DISPATCH_SIZE);
+               if (dispatch_buf == NULL) {
+                       error = CS_ERR_NO_MEMORY;
+                       goto error_put;
+               }
+       }
+
        dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
        do {
                errno_res = qb_ipcc_event_recv (
@@ -503,6 +534,11 @@ cs_error_t cpg_dispatch (
        } while (cont);
 
 error_put:
+       if (owner || cpg_inst->finalize) {
+               free(dispatch_buf);
+       } else {
+               qb_atomic_int_set(&cpg_inst->in_dispatch, 0);
+       }
        hdb_handle_put (&cpg_handle_t_db, handle);
        return (error);
 }

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
discuss mailing list
[email protected]
http://lists.corosync.org/mailman/listinfo/discuss

Reply via email to