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 discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss