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);
}
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ discuss mailing list [email protected] http://lists.corosync.org/mailman/listinfo/discuss
