@@ -1480,6 +1480,123 @@ static double Mean(const size_t cSamples,
14801480 return mean;
14811481}
14821482
1483+ // we don't care if an extra log message is outputted due to the non-atomic nature of the decrement to this value
1484+ static int g_cLogEnterSafeSumCount = 25 ;
1485+ static int g_cLogExitSafeSumCount = 25 ;
1486+
1487+ EBM_API_BODY ErrorEbm EBM_CALLING_CONVENTION SafeSum (
1488+ IntEbm countDistant, IntEbm countAxis, IntEbm countClose, const double * in, double * out) {
1489+
1490+ LOG_COUNTED_N (&g_cLogEnterSafeSumCount,
1491+ Trace_Info,
1492+ Trace_Verbose,
1493+ " Entered SafeSum: "
1494+ " countDistant=%" IntEbmPrintf " , "
1495+ " countAxis=%" IntEbmPrintf " , "
1496+ " countClose=%" IntEbmPrintf " , "
1497+ " in=%p, "
1498+ " out=%p" ,
1499+ countDistant,
1500+ countAxis,
1501+ countClose,
1502+ static_cast <const void *>(in),
1503+ static_cast <const void *>(out));
1504+
1505+ if (nullptr == in) {
1506+ LOG_0 (Trace_Error, " ERROR SafeSum nullptr == in" );
1507+ return Error_IllegalParamVal;
1508+ }
1509+
1510+ if (nullptr == out) {
1511+ LOG_0 (Trace_Error, " ERROR SafeSum nullptr == out" );
1512+ return Error_IllegalParamVal;
1513+ }
1514+
1515+ if (countDistant <= IntEbm{0 }) {
1516+ if (countDistant < IntEbm{0 }) {
1517+ LOG_0 (Trace_Error, " ERROR SafeSum countDistant < IntEbm{0}" );
1518+ return Error_IllegalParamVal;
1519+ }
1520+ return Error_None;
1521+ }
1522+ if (IsConvertError<size_t >(countDistant)) {
1523+ LOG_0 (Trace_Error, " ERROR SafeSum IsConvertError<size_t>(countDistant)" );
1524+ return Error_IllegalParamVal;
1525+ }
1526+ const size_t cDistant = static_cast <size_t >(countDistant);
1527+
1528+ if (countClose <= IntEbm{0 }) {
1529+ if (countClose < IntEbm{0 }) {
1530+ LOG_0 (Trace_Error, " ERROR SafeSum countClose < IntEbm{0}" );
1531+ return Error_IllegalParamVal;
1532+ }
1533+ return Error_None;
1534+ }
1535+ if (IsConvertError<size_t >(countClose)) {
1536+ LOG_0 (Trace_Error, " ERROR SafeSum IsConvertError<size_t>(countClose)" );
1537+ return Error_IllegalParamVal;
1538+ }
1539+ const size_t cClose = static_cast <size_t >(countClose);
1540+
1541+ if (IsMultiplyError (sizeof (double ), cClose)) {
1542+ LOG_0 (Trace_Error, " ERROR SafeSum IsMultiplyError(sizeof(double), cClose)" );
1543+ return Error_IllegalParamVal;
1544+ }
1545+ const size_t cCloseBytes = sizeof (double ) * cClose;
1546+
1547+ if (IsMultiplyError (cCloseBytes, cDistant)) {
1548+ LOG_0 (Trace_Error, " ERROR SafeSum IsMultiplyError(cCloseBytes, cDistant)" );
1549+ return Error_IllegalParamVal;
1550+ }
1551+ const size_t cNonAxisBytes = cCloseBytes * cDistant;
1552+
1553+ if (countAxis <= IntEbm{1 }) {
1554+ if (IntEbm{1 } == countAxis) {
1555+ memcpy (out, in, cNonAxisBytes);
1556+ } else if (countAxis < IntEbm{0 }) {
1557+ LOG_0 (Trace_Error, " ERROR SafeSum countAxis < IntEbm{0}" );
1558+ return Error_IllegalParamVal;
1559+ }
1560+ return Error_None;
1561+ }
1562+ if (IsConvertError<size_t >(countAxis)) {
1563+ LOG_0 (Trace_Error, " ERROR SafeSum IsConvertError<size_t>(countAxis)" );
1564+ return Error_IllegalParamVal;
1565+ }
1566+ const size_t cAxis = static_cast <size_t >(countAxis);
1567+
1568+ if (IsMultiplyError (cNonAxisBytes, cAxis)) {
1569+ LOG_0 (Trace_Error, " ERROR SafeSum IsMultiplyError(cNonAxisBytes, cAxis)" );
1570+ return Error_IllegalParamVal;
1571+ }
1572+
1573+ const double * const pOutEnd = IndexByte (out, cNonAxisBytes);
1574+ const size_t cAxisBytes = cCloseBytes * cAxis;
1575+ const size_t cNext = sizeof (*in) - cAxisBytes;
1576+ const size_t cNextGrouping = cAxisBytes - cCloseBytes;
1577+ size_t i = 0 ;
1578+ do {
1579+ const double * const pCloseEnd = IndexByte (out, cCloseBytes);
1580+ do {
1581+ const size_t iEnd = i + cAxisBytes;
1582+ double sum = *IndexByte (in, i);
1583+ i += cCloseBytes;
1584+ do {
1585+ sum += *IndexByte (in, i);
1586+ i += cCloseBytes;
1587+ } while (iEnd != i);
1588+ i += cNext;
1589+ *out = sum;
1590+ ++out;
1591+ } while (pCloseEnd != out);
1592+ i += cNextGrouping;
1593+ } while (pOutEnd != out);
1594+
1595+ LOG_COUNTED_0 (&g_cLogExitSafeSumCount, Trace_Info, Trace_Verbose, " Exited SafeSum" );
1596+
1597+ return Error_None;
1598+ }
1599+
14831600// we don't care if an extra log message is outputted due to the non-atomic nature of the decrement to this value
14841601static int g_cLogEnterSafeMeanCount = 25 ;
14851602static int g_cLogExitSafeMeanCount = 25 ;
0 commit comments