From 70f12fb1fdd711bcbea0ac0b91ff4a402c879a62 Mon Sep 17 00:00:00 2001 From: rlar Date: Mon, 30 Dec 2013 17:19:07 +0100 Subject: [PATCH] analog/{sine,square,triangle}, xtradev/core, change array access avoid copy of parameter array, which would need to be freed to avoid a memory leak this is a modified and partial version of a patch provided by Krzysztof Blaszkowski --- src/xspice/icm/analog/sine/cfunc.mod | 64 ++++------------- src/xspice/icm/analog/sine/ifspec.ifs | 6 -- src/xspice/icm/analog/square/cfunc.mod | 51 ++++---------- src/xspice/icm/analog/triangle/cfunc.mod | 53 +++++---------- src/xspice/icm/xtradev/core/cfunc.mod | 87 +++++++----------------- src/xspice/icm/xtradev/core/ifspec.ifs | 6 -- 6 files changed, 72 insertions(+), 195 deletions(-) diff --git a/src/xspice/icm/analog/sine/cfunc.mod b/src/xspice/icm/analog/sine/cfunc.mod index eb6a87685..139dacd84 100644 --- a/src/xspice/icm/analog/sine/cfunc.mod +++ b/src/xspice/icm/analog/sine/cfunc.mod @@ -72,13 +72,6 @@ char *array_error = "\n**** Error ****\nSINE: Size of control array different th /*=== LOCAL VARIABLES & TYPEDEFS =======*/ -typedef struct { - double *control; /* the storage array for the - control vector (cntl_array) */ - double *freq; /* the storage array for the - frequency vector (freq_array) */ -} Local_Data_t; - /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ @@ -133,8 +126,8 @@ cm_sine(ARGS) int cntl_size; /* control array size */ int freq_size; /* frequency array size */ - double *x; /* pointer to the control array values */ - double *y; /* pointer to the frequency array values */ + Mif_Value_t *x; /* pointer to the control array values */ + Mif_Value_t *y; /* pointer to the frequency array values */ double cntl_input; /* control input */ double dout_din; /* partial derivative of output wrt control in */ double output_low; /* output low value */ @@ -148,9 +141,6 @@ cm_sine(ARGS) Mif_Complex_t ac_gain; - Local_Data_t *loc; /* Pointer to local static data, not to be included - in the state vector */ - /**** Retrieve frequently used parameters... ****/ cntl_size = PARAM_SIZE(cntl_array); @@ -167,24 +157,11 @@ cm_sine(ARGS) cm_analog_alloc(INT1, sizeof(double)); - /*** allocate static storage for *loc ***/ - STATIC_VAR(locdata) = calloc(1, sizeof(Local_Data_t)); - loc = STATIC_VAR(locdata); - - /* Allocate storage for breakpoint domain & freq. range values */ - x = loc->control = (double *) calloc((size_t) cntl_size, sizeof(double)); - if (!x) { - cm_message_send(allocation_error); - return; - } - y = loc->freq = (double *) calloc((size_t) freq_size, sizeof(double)); - if (!y) { - cm_message_send(allocation_error); - return; - } - } + x = (Mif_Value_t*) &PARAM(cntl_array[0]); + y = (Mif_Value_t*) &PARAM(freq_array[0]); + if (ANALYSIS == MIF_DC) { OUTPUT(out) = (output_hi + output_low) / 2; @@ -197,38 +174,27 @@ cm_sine(ARGS) phase = (double *) cm_analog_get_ptr(INT1, 0); phase1 = (double *) cm_analog_get_ptr(INT1, 1); - loc = STATIC_VAR(locdata); - - x = loc->control; - y = loc->freq; - - /* Retrieve x and y values. */ - for (i = 0; i < cntl_size; i++) { - x[i] = PARAM(cntl_array[i]); - y[i] = PARAM(freq_array[i]); - } - /* Retrieve cntl_input value. */ cntl_input = INPUT(cntl_in); /* Determine segment boundaries within which cntl_input resides */ - if (cntl_input <= *x) { + if (cntl_input <= x[0].rvalue) { /*** cntl_input below lowest cntl_voltage ***/ - dout_din = (y[1] - y[0]) / (x[1] - x[0]); - freq = *y + (cntl_input - *x) * dout_din; + dout_din = (y[1].rvalue - y[0].rvalue) / (x[1].rvalue - x[0].rvalue); + freq = y[0].rvalue + (cntl_input - x[0].rvalue) * dout_din; if (freq <= 0) { cm_message_send(sine_freq_clamp); freq = 1e-16; } - } else if (cntl_input >= x[cntl_size-1]) { + } else if (cntl_input >= x[cntl_size-1].rvalue) { /*** cntl_input above highest cntl_voltage ***/ - dout_din = (y[cntl_size-1] - y[cntl_size-2]) / - (x[cntl_size-1] - x[cntl_size-2]); - freq = y[cntl_size-1] + (cntl_input - x[cntl_size-1]) * dout_din; + dout_din = (y[cntl_size-1].rvalue - y[cntl_size-2].rvalue) / + (x[cntl_size-1].rvalue - x[cntl_size-2].rvalue); + freq = y[cntl_size-1].rvalue + (cntl_input - x[cntl_size-1].rvalue) * dout_din; } else { @@ -237,10 +203,10 @@ cm_sine(ARGS) calculate required output. ***/ for (i = 0; i < cntl_size - 1; i++) - if ((cntl_input < x[i+1]) && (cntl_input >= x[i])) { + if ((cntl_input < x[i+1].rvalue) && (cntl_input >= x[i].rvalue)) { /* Interpolate to the correct frequency value */ - freq = ((cntl_input - x[i]) / (x[i+1] - x[i])) * - (y[i+1] - y[i]) + y[i]; + freq = ((cntl_input - x[i].rvalue) / (x[i+1].rvalue - x[i].rvalue)) * + (y[i+1].rvalue - y[i].rvalue) + y[i].rvalue; } } diff --git a/src/xspice/icm/analog/sine/ifspec.ifs b/src/xspice/icm/analog/sine/ifspec.ifs index 94f0345ed..fa0e92a71 100644 --- a/src/xspice/icm/analog/sine/ifspec.ifs +++ b/src/xspice/icm/analog/sine/ifspec.ifs @@ -58,9 +58,3 @@ Vector: no no Vector_Bounds: - - Null_Allowed: yes yes - -STATIC_VAR_TABLE: - -Static_Var_Name: locdata -Description: "local static data" -Data_Type: pointer diff --git a/src/xspice/icm/analog/square/cfunc.mod b/src/xspice/icm/analog/square/cfunc.mod index e7f8f70c2..6920cd6f8 100644 --- a/src/xspice/icm/analog/square/cfunc.mod +++ b/src/xspice/icm/analog/square/cfunc.mod @@ -74,10 +74,6 @@ char *square_array_error = "\n**** Error ****\nSQUARE: Size of control array dif /*=== LOCAL VARIABLES & TYPEDEFS =======*/ typedef struct { - double *control; /* the storage array for the - control vector (cntl_array) */ - double *freq; /* the storage array for the - pulse width array (pw_array) */ Boolean_t tran_init; /* for initialization of phase1) */ } Local_Data_t; @@ -159,8 +155,8 @@ cm_square(ARGS) int freq_size; /* frequency array size */ int int_cycle; /* integer number of cycles */ - double *x; /* pointer to the control array values */ - double *y; /* pointer to the frequecy array values */ + Mif_Value_t *x; /* pointer to the control array values */ + Mif_Value_t *y; /* pointer to the frequency array values */ double cntl_input; /* control input */ double dout_din; /* slope of the frequency array wrt the control array. Used to extrapolate a frequency above @@ -218,21 +214,12 @@ cm_square(ARGS) STATIC_VAR(locdata) = calloc(1, sizeof(Local_Data_t)); loc = STATIC_VAR(locdata); - /* Allocate storage for breakpoint domain & pulse width values */ - x = loc->control = (double *) calloc((size_t) cntl_size, sizeof(double)); - if (!x) { - cm_message_send(square_allocation_error); - return; - } - y = loc->freq = (double *) calloc((size_t) freq_size, sizeof(double)); - if (!y) { - cm_message_send(square_allocation_error); - return; - } - loc->tran_init = FALSE; } + x = (Mif_Value_t*) &PARAM(cntl_array[0]); + y = (Mif_Value_t*) &PARAM(freq_array[0]); + if (ANALYSIS == MIF_DC) { /* initialize time values */ @@ -267,39 +254,31 @@ cm_square(ARGS) time4 = *t4; loc = STATIC_VAR(locdata); - x = loc->control; - y = loc->freq; if (!loc->tran_init) { *phase1 = 0.0; loc->tran_init = TRUE; } - /* Retrieve x and y values. */ - for (i = 0; i < cntl_size; i++) { - x[i] = PARAM(cntl_array[i]); - y[i] = PARAM(freq_array[i]); - } - /* Retrieve cntl_input value. */ cntl_input = INPUT(cntl_in); /* Determine segment boundaries within which cntl_input resides */ /*** cntl_input below lowest cntl_voltage ***/ - if (cntl_input <= *x) { - dout_din = (y[1] - y[0]) / (x[1] - x[0]); - freq = *y + (cntl_input - *x) * dout_din; + if (cntl_input <= x[0].rvalue) { + dout_din = (y[1].rvalue - y[0].rvalue) / (x[1].rvalue - x[0].rvalue); + freq = y[0].rvalue + (cntl_input - x[0].rvalue) * dout_din; if (freq <= 0) { cm_message_send(square_freq_clamp); freq = 1e-16; } - } else if (cntl_input >= x[cntl_size-1]) { + } else if (cntl_input >= x[cntl_size-1].rvalue) { /*** cntl_input above highest cntl_voltage ***/ - dout_din = (y[cntl_size-1] - y[cntl_size-2]) / - (x[cntl_size-1] - x[cntl_size-2]); - freq = y[cntl_size-1] + (cntl_input - x[cntl_size-1]) * dout_din; + dout_din = (y[cntl_size-1].rvalue - y[cntl_size-2].rvalue) / + (x[cntl_size-1].rvalue - x[cntl_size-2].rvalue); + freq = y[cntl_size-1].rvalue + (cntl_input - x[cntl_size-1].rvalue) * dout_din; } else { /*** cntl_input within bounds of end midpoints... @@ -308,12 +287,12 @@ cm_square(ARGS) for (i = 0; i < cntl_size - 1; i++) { - if ((cntl_input < x[i+1]) && (cntl_input >= x[i])) { + if ((cntl_input < x[i+1].rvalue) && (cntl_input >= x[i].rvalue)) { /* Interpolate to the correct frequency value */ - freq = ((cntl_input - x[i])/(x[i+1] - x[i])) * - (y[i+1]-y[i]) + y[i]; + freq = ((cntl_input - x[i].rvalue)/(x[i+1].rvalue - x[i].rvalue)) * + (y[i+1].rvalue-y[i].rvalue) + y[i].rvalue; } } diff --git a/src/xspice/icm/analog/triangle/cfunc.mod b/src/xspice/icm/analog/triangle/cfunc.mod index 9bef9725c..69521c8c7 100644 --- a/src/xspice/icm/analog/triangle/cfunc.mod +++ b/src/xspice/icm/analog/triangle/cfunc.mod @@ -73,10 +73,6 @@ char *triangle_array_error = "\n**** Error ****\nTRIANGLE: Size of control array /*=== LOCAL VARIABLES & TYPEDEFS =======*/ typedef struct { - double *control; /* the storage array for the - control vector (cntl_array) */ - double *freq; /* the storage array for the - pulse width array (pw_array) */ int tran_init; /* for initialization of phase1) */ } Local_Data_t; @@ -159,8 +155,8 @@ cm_triangle(ARGS) int freq_size; /* size of the frequency array */ int int_cycle; /* the number of cycles rounded to the nearest int */ - double *x; /* pointer holds the values of the control array */ - double *y; /* pointer holds the values of the freq array */ + Mif_Value_t *x; /* pointer holds the values of the control array */ + Mif_Value_t *y; /* pointer holds the values of the freq array */ double cntl_input; /* control input */ double dout_din; /* partial out wrt to control input */ @@ -209,21 +205,12 @@ cm_triangle(ARGS) STATIC_VAR(locdata) = calloc(1, sizeof(Local_Data_t)); loc = STATIC_VAR(locdata); - /* Allocate storage for breakpoint domain & pulse width values */ - x = loc->control = (double *) calloc((size_t) cntl_size, sizeof(double)); - if (!x) { - cm_message_send(triangle_allocation_error); - return; - } - y = loc->freq = (double *) calloc((size_t) freq_size, sizeof(double)); - if (!y) { - cm_message_send(triangle_allocation_error); - return; - } - loc->tran_init = FALSE; } + x = (Mif_Value_t*) &PARAM(cntl_array[0]); + y = (Mif_Value_t*) &PARAM(freq_array[0]); + if (ANALYSIS == MIF_DC) { /* initialize time values */ @@ -255,42 +242,34 @@ cm_triangle(ARGS) t_start = *t_end; loc = STATIC_VAR(locdata); - x = loc->control; - y = loc->freq; if (! loc->tran_init) { *phase1 = 0.0; loc->tran_init = TRUE; } - /* Retrieve x and y values. */ - for (i = 0; i < cntl_size; i++) { - x[i] = PARAM(cntl_array[i]); - y[i] = PARAM(freq_array[i]); - } - /* Retrieve cntl_input value. */ cntl_input = INPUT(cntl_in); /* Determine segment boundaries within which cntl_input resides */ /*** cntl_input below lowest cntl_voltage ***/ - if (cntl_input <= *x) { + if (cntl_input <= x[0].rvalue) { - dout_din = (y[1] - y[0]) / (x[1] - x[0]); - freq = *y + (cntl_input - *x) * dout_din; + dout_din = (y[1].rvalue - y[0].rvalue) / (x[1].rvalue - x[0].rvalue); + freq = y[0].rvalue + (cntl_input - x[0].rvalue) * dout_din; if (freq <= 0) { cm_message_send(triangle_freq_clamp); freq = 1e-16; } - } else if (cntl_input >= x[cntl_size-1]) { + } else if (cntl_input >= x[cntl_size-1].rvalue) { /*** cntl_input above highest cntl_voltage ***/ - dout_din = (y[cntl_size-1] - y[cntl_size-2]) / - (x[cntl_size-1] - x[cntl_size-2]); - freq = y[cntl_size-1] + (cntl_input - x[cntl_size-1]) * dout_din; - /* freq = y[cntl_size-1]; */ + dout_din = (y[cntl_size-1].rvalue - y[cntl_size-2].rvalue) / + (x[cntl_size-1].rvalue - x[cntl_size-2].rvalue); + freq = y[cntl_size-1].rvalue + (cntl_input - x[cntl_size-1].rvalue) * dout_din; + /* freq = y[cntl_size-1].rvalue; */ } else { /*** cntl_input within bounds of end midpoints... @@ -299,12 +278,12 @@ cm_triangle(ARGS) for (i = 0; i < cntl_size - 1; i++) { - if ((cntl_input < x[i+1]) && (cntl_input >= x[i])) { + if ((cntl_input < x[i+1].rvalue) && (cntl_input >= x[i].rvalue)) { /* Interpolate to the correct frequency value */ - freq = ((cntl_input - x[i]) / (x[i+1] - x[i])) * - (y[i+1] - y[i]) + y[i]; + freq = ((cntl_input - x[i].rvalue) / (x[i+1].rvalue - x[i].rvalue)) * + (y[i+1].rvalue - y[i].rvalue) + y[i].rvalue; } } } diff --git a/src/xspice/icm/xtradev/core/cfunc.mod b/src/xspice/icm/xtradev/core/cfunc.mod index bf06d6e80..d88f691f9 100644 --- a/src/xspice/icm/xtradev/core/cfunc.mod +++ b/src/xspice/icm/xtradev/core/cfunc.mod @@ -66,14 +66,6 @@ NON-STANDARD FEATURES /*=== LOCAL VARIABLES & TYPEDEFS =======*/ -typedef struct { - double *H_array; /* the storage array for the - control vector (cntl_array) */ - double *B_array; /* the storage array for the - pulse width array (pw_array) */ - Boolean_t tran_init; /* for initialization of phase1) */ -} Local_Data_t; - /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ @@ -197,8 +189,8 @@ cm_core(ARGS) double input_domain; /* smoothing range */ - double *H; /* pointer to the H-field array */ - double *B; /* pointer to the B-field array */ + Mif_Value_t *H; /* pointer to the H-field array */ + Mif_Value_t *B; /* pointer to the B-field array */ double lower_seg; /* x segment below which input resides */ double upper_seg; /* x segment above which the input resides */ double lower_slope; /* slope of the lower segment */ @@ -216,7 +208,6 @@ cm_core(ARGS) Mif_Complex_t ac_gain; - char *allocation_error="\n***ERROR***\nCORE: Allocation calloc failed!\n"; char *limit_error="\n***ERROR***\nCORE: Violation of 50% rule in breakpoints!\n"; @@ -250,9 +241,6 @@ cm_core(ARGS) in_low - hyst and +infinity */ *old_hyst_state; /* previous value of *hyst_state */ - Local_Data_t *loc; /* Pointer to local static data, not to be included - in the state vector */ - /* Retrieve mode parameter... */ mode = PARAM(mode); @@ -270,40 +258,14 @@ cm_core(ARGS) size = PARAM_SIZE(H_array); - if (INIT == 1) { - - /*** allocate static storage for *loc ***/ - STATIC_VAR(locdata) = calloc(1, sizeof(Local_Data_t)); - loc = STATIC_VAR(locdata); - - /* Allocate storage for breakpoint domain & range values */ - H = loc->H_array = (double *) calloc((size_t) size, sizeof(double)); - if (!H) { - cm_message_send(allocation_error); - return; - } - B = loc->B_array = (double *) calloc((size_t) size, sizeof(double)); - if (!B) { - cm_message_send(allocation_error); - return; - } - } - - loc = STATIC_VAR(locdata); - H = loc->H_array; - B = loc->B_array; - - /* Retrieve H and B values. */ - for (i = 0; i < size; i++) { - H[i] = PARAM(H_array[i]); - B[i] = PARAM(B_array[i]); - } + H = (Mif_Value_t*) &PARAM(H_array[0]); + B = (Mif_Value_t*) &PARAM(B_array[0]); /* See if input_domain is absolute...if so, test against */ /* breakpoint segments for violation of 50% rule... */ if (PARAM(fraction) == MIF_FALSE) for (i = 0; i < size - 1; i++) - if ((H[i+1] - H[i]) < 2.0 * input_domain) { + if ((H[i+1].rvalue - H[i].rvalue) < 2.0 * input_domain) { cm_message_send(limit_error); return; } @@ -316,28 +278,31 @@ cm_core(ARGS) /* Determine segment boundaries within which H_input resides */ - if (H_input <= (H[1] + H[0]) / 2.0) {/*** H_input below lowest midpoint ***/ + if (H_input <= (H[1].rvalue + H[0].rvalue) / 2.0) {/*** H_input below lowest midpoint ***/ - dout_din = (B[1] - B[0]) / (H[1] - H[0]); - B_out = *B + (H_input - *H) * dout_din; + dout_din = (B[1].rvalue - B[0].rvalue) / (H[1].rvalue - H[0].rvalue); + B_out = B[0].rvalue + (H_input - H[0].rvalue) * dout_din; - } else if (H_input >= (H[size-2] + H[size-1]) / 2.0) { + } else if (H_input >= (H[size-2].rvalue + H[size-1].rvalue) / 2.0) { /*** H_input above highest midpoint ***/ - dout_din = (B[size-1] - B[size-2]) / (H[size-1] - H[size-2]); - B_out = B[size-1] + (H_input - H[size-1]) * dout_din; + dout_din = (B[size-1].rvalue - B[size-2].rvalue) / (H[size-1].rvalue - H[size-2].rvalue); + B_out = B[size-1].rvalue + (H_input - H[size-1].rvalue) * dout_din; } else { /*** H_input within bounds of end midpoints... ***/ /*** must determine position progressively & then ***/ /*** calculate required output. ***/ + dout_din = 0.0 / 0.0; + B_out = 0.0 / 0.0; + for (i = 1; i < size; i++) - if (H_input < (H[i] + H[i+1]) / 2.0) { + if (H_input < (H[i].rvalue + H[i+1].rvalue) / 2.0) { /* approximate position known... */ - lower_seg = (H[i] - H[i-1]); - upper_seg = (H[i+1] - H[i]); + lower_seg = (H[i].rvalue - H[i-1].rvalue); + upper_seg = (H[i+1].rvalue - H[i].rvalue); /* Calculate input_domain about this region's breakpoint.*/ @@ -354,27 +319,27 @@ cm_core(ARGS) } /* Set up threshold values about breakpoint... */ - threshold_lower = H[i] - input_domain; - threshold_upper = H[i] + input_domain; + threshold_lower = H[i].rvalue - input_domain; + threshold_upper = H[i].rvalue + input_domain; /* Determine where H_input is within region & determine */ /* output and partial values.... */ if (H_input < threshold_lower) { /* Lower linear region */ - dout_din = (B[i] - B[i-1]) / lower_seg; - B_out = B[i] + (H_input - H[i]) * dout_din; + dout_din = (B[i].rvalue - B[i-1].rvalue) / lower_seg; + B_out = B[i].rvalue + (H_input - H[i].rvalue) * dout_din; } else if (H_input < threshold_upper) { /* Parabolic region */ - lower_slope = (B[i] - B[i-1]) / lower_seg; - upper_slope = (B[i+1] - B[i]) / upper_seg; - cm_smooth_corner(H_input, H[i], B[i], input_domain, + lower_slope = (B[i].rvalue - B[i-1].rvalue) / lower_seg; + upper_slope = (B[i+1].rvalue - B[i].rvalue) / upper_seg; + cm_smooth_corner(H_input, H[i].rvalue, B[i].rvalue, input_domain, lower_slope, upper_slope, &B_out, &dout_din); } else { /* Upper linear region */ - dout_din = (B[i+1] - B[i]) / upper_seg; - B_out = B[i] + (H_input - H[i]) * dout_din; + dout_din = (B[i+1].rvalue - B[i].rvalue) / upper_seg; + B_out = B[i].rvalue + (H_input - H[i].rvalue) * dout_din; } diff --git a/src/xspice/icm/xtradev/core/ifspec.ifs b/src/xspice/icm/xtradev/core/ifspec.ifs index 598ee2b0d..4d15403f1 100644 --- a/src/xspice/icm/xtradev/core/ifspec.ifs +++ b/src/xspice/icm/xtradev/core/ifspec.ifs @@ -131,9 +131,3 @@ Vector: no Vector_Bounds: - Null_Allowed: yes - -STATIC_VAR_TABLE: - -Static_Var_Name: locdata -Description: "local static data" -Data_Type: pointer