Blame IbAccess/Common/Public/imemory.c

Packit 857059
/* BEGIN_ICS_COPYRIGHT6 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015-2017, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
      documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT6   ****************************************/
Packit 857059
Packit 857059
#if !defined(VXWORKS)
Packit 857059
#define _GNU_SOURCE
Packit 857059
#endif
Packit 857059
Packit 857059
#include "imemory.h"
Packit 857059
#include "idebug.h"
Packit 857059
#include "itimer.h"
Packit 857059
#include <stdarg.h>
Packit 857059
#include <errno.h>
Packit 857059
#include <stdlib.h>
Packit 857059
#include <unistd.h>
Packit 857059
#include <ctype.h>
Packit 857059
Packit 857059
#define MAX_VFABRIC_NAME	64	// from fm_xml.h
Packit 857059
Packit 857059
// from stl_pa.h
Packit 857059
#define STL_PA_SELECT_UTIL_HIGH			0x00020001
Packit 857059
#define STL_PA_SELECT_UTIL_MC_HIGH		0x00020081
Packit 857059
#define STL_PA_SELECT_UTIL_PKTS_HIGH		0x00020082
Packit 857059
#define STL_PA_SELECT_CATEGORY_INTEG			0x00030001
Packit 857059
#define STL_PA_SELECT_CATEGORY_CONG			0x00030002
Packit 857059
#define STL_PA_SELECT_CATEGORY_SMA_CONG		0x00030003
Packit 857059
#define STL_PA_SELECT_CATEGORY_BUBBLE		0x00030004
Packit 857059
#define STL_PA_SELECT_CATEGORY_SEC			0x00030005
Packit 857059
#define STL_PA_SELECT_CATEGORY_ROUT			0x00030006
Packit 857059
#define FOCUS_PORTS_COMPARATOR_INVALID			0
Packit 857059
#define FOCUS_PORTS_COMPARATOR_GREATER_THAN		1
Packit 857059
#define FOCUS_PORTS_COMPARATOR_LESS_THAN		2
Packit 857059
#define FOCUS_PORTS_COMPARATOR_GREATER_THAN_OR_EQUAL	3
Packit 857059
#define FOCUS_PORTS_COMPARATOR_LESS_THAN_OR_EQUAL	4
Packit 857059
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
#if defined(VXWORKS)
Packit 857059
#include "tickLib.h"
Packit 857059
#define TICK tickGet()
Packit 857059
#else
Packit 857059
#define TICK 0 // TBD need to specify value for Linux and MAC
Packit 857059
#endif
Packit 857059
#define MEM_TRACK_FTR
Packit 857059
#include "imemtrack.h"
Packit 857059
Packit 857059
// Default number of headers to allocate at a time.
Packit 857059
#define MEM_HDR_ALLOC_SIZE	50
Packit 857059
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
#define UNTRACKED_COUNT 12000
Packit 857059
void *unTAddr[UNTRACKED_COUNT];
Packit 857059
int unTindex=0;
Packit 857059
int unTmissed=0;
Packit 857059
#endif
Packit 857059
Packit 857059
MEM_TRACKER	*pMemTracker = NULL;
Packit 857059
static uint32 last_reported_allocations;
Packit 857059
static uint32 total_allocations;
Packit 857059
static uint32 last_reported_secs;
Packit 857059
static uint32 current_allocations;
Packit 857059
static uint32 current_allocated;
Packit 857059
static uint32 max_allocations;
Packit 857059
static uint32 max_allocated;
Packit 857059
Packit 857059
static void MemoryTrackerDereference(MemoryTrackerFileName_t *trk);
Packit 857059
static MemoryTrackerFileName_t *MemoryTrackerBuckets[MEMORY_TRACKER_BUCKETS];
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
Packit 857059
#ifdef VXWORKS
Packit 857059
extern unsigned long long strtoull (const char *__s, char **__endptr, int __base);
Packit 857059
extern long long strtoll (const char *__s, char **__endptr, int __base);
Packit 857059
#endif
Packit 857059
Packit 857059
char*
Packit 857059
StringConcat(const char* str1, ...)
Packit 857059
{
Packit 857059
#ifdef VXWORKS
Packit 857059
#define stpcpy(s1, s2) (strcpy(s1, s2) + strlen(s2))
Packit 857059
#endif
Packit 857059
Packit 857059
	if (!str1)
Packit 857059
		return NULL;
Packit 857059
Packit 857059
	/* calculate length first */
Packit 857059
	size_t strings_length = 1 + strlen(str1);
Packit 857059
Packit 857059
	va_list args;
Packit 857059
	va_start(args, str1);
Packit 857059
	char* str = va_arg(args, char*);
Packit 857059
	while (str) {
Packit 857059
		strings_length += strlen(str);
Packit 857059
		str = va_arg(args, char*);
Packit 857059
	}
Packit 857059
	va_end(args);
Packit 857059
Packit 857059
	/* next, allocate a memory */
Packit 857059
	char* string = (char*)malloc(strings_length);
Packit 857059
	if (!string)
Packit 857059
		return NULL;
Packit 857059
Packit 857059
	/* finally, create the string */
Packit 857059
	char* string_tmp = stpcpy(string, str1);
Packit 857059
	va_start(args, str1);
Packit 857059
	str = va_arg(args, char*);
Packit 857059
	while (str) {
Packit 857059
		string_tmp = stpcpy(string_tmp, str);
Packit 857059
		str = va_arg(args, char*);
Packit 857059
	}
Packit 857059
	va_end(args);
Packit 857059
Packit 857059
	return string;
Packit 857059
}
Packit 857059
Packit 857059
// convert a string to a uint64.  Very similar to strtoull except that
Packit 857059
// base=0 implies base 10 or 16, but excludes base 8
Packit 857059
// hence allowing leading 0's for base 10.
Packit 857059
//
Packit 857059
// Also provides easier to use status returns and error checking.
Packit 857059
//
Packit 857059
// Can also optionally skip trailing whitespace, when skip_trail_whietspace is
Packit 857059
// FALSE, trailing whitespace is treated as a FERROR
Packit 857059
//
Packit 857059
// When endptr is NULL, trailing characters (after optional whitespace) are 
Packit 857059
// considered an FERROR.  When endptr is non-NULL, for a FSUCCESS conversion,
Packit 857059
// it points to the characters after the optional trailing whitespace.
Packit 857059
// Errors:
Packit 857059
//	FSUCCESS - successful conversion, *endptr points to 1st char after value
Packit 857059
//	FERROR - invalid contents, non-numeric
Packit 857059
//	FINVALID_SETTING - value out of range
Packit 857059
//	FINVALID_PARAMETER - invalid function arguments (NULL value or str)
Packit 857059
FSTATUS StringToUint64(uint64 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	char *end = NULL;
Packit 857059
	uint64 temp;
Packit 857059
Packit 857059
	if (! str || ! value)
Packit 857059
		return FINVALID_PARAMETER;
Packit 857059
	errno = 0;
Packit 857059
	temp = strtoull(str, &end, base?base:10);
Packit 857059
	if ( ! base && ! (temp == IB_UINT64_MAX && errno)
Packit 857059
		&& (end && temp == 0 && *end == 'x' && end != str)) {
Packit 857059
		// try again as base 16
Packit 857059
		temp = strtoull(str, &end, 16);
Packit 857059
	}
Packit 857059
	if ((temp == IB_UINT64_MAX && errno)
Packit 857059
		|| (end && end == str)) {
Packit 857059
		if (errno == ERANGE)
Packit 857059
			return FINVALID_SETTING;
Packit 857059
		else
Packit 857059
			return FERROR;
Packit 857059
	}
Packit 857059
Packit 857059
	// skip whitespace
Packit 857059
	if (end && skip_trail_whitespace) {
Packit 857059
		while (isspace(*end)) {
Packit 857059
			end++;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	if (endptr)
Packit 857059
		*endptr = end;
Packit 857059
	else if (end && *end != '\0')
Packit 857059
		return FERROR;
Packit 857059
	*value = temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
FSTATUS StringToUint32(uint32 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	uint64 temp;
Packit 857059
	FSTATUS status;
Packit 857059
Packit 857059
	status = StringToUint64(&temp, str, endptr, base, skip_trail_whitespace);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if (temp > IB_UINT32_MAX)
Packit 857059
		return FINVALID_SETTING;
Packit 857059
	*value = (uint32)temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
FSTATUS StringToUint16(uint16 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	uint64 temp;
Packit 857059
	FSTATUS status;
Packit 857059
Packit 857059
	status = StringToUint64(&temp, str, endptr, base, skip_trail_whitespace);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if (temp > IB_UINT16_MAX)
Packit 857059
		return FINVALID_SETTING;
Packit 857059
	*value = (uint16)temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
FSTATUS StringToUint8(uint8 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	uint64 temp;
Packit 857059
	FSTATUS status;
Packit 857059
Packit 857059
	status = StringToUint64(&temp, str, endptr, base, skip_trail_whitespace);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if (temp > IB_UINT8_MAX)
Packit 857059
		return FINVALID_SETTING;
Packit 857059
	*value = (uint8)temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
// convert a string to a int64.  Very similar to strtoull except that
Packit 857059
// base=0 implies base 10 or 16, but excludes base 8
Packit 857059
// hence allowing leading 0's for base 10.
Packit 857059
//
Packit 857059
// Also provides easier to use status returns and error checking.
Packit 857059
//
Packit 857059
// Can also optionally skip trailing whitespace, when skip_trail_whitespace is
Packit 857059
// FALSE, trailing whitespace is treated as a FERROR
Packit 857059
//
Packit 857059
// When endptr is NULL, trailing characters (after optional whitespace) are 
Packit 857059
// considered an FERROR.  When endptr is non-NULL, for a FSUCCESS conversion,
Packit 857059
// it points to the characters after the optional trailing whitespace.
Packit 857059
// Errors:
Packit 857059
//	FSUCCESS - successful conversion, *endptr points to 1st char after value
Packit 857059
//	FERROR - invalid contents, non-numeric
Packit 857059
//	FINVALID_SETTING - value out of range
Packit 857059
//	FINVALID_PARAMETER - invalid function arguments (NULL value or str)
Packit 857059
FSTATUS StringToInt64(int64 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	char *end = NULL;
Packit 857059
	int64 temp;
Packit 857059
Packit 857059
	if (! str || ! value)
Packit 857059
		return FINVALID_PARAMETER;
Packit 857059
	errno = 0;
Packit 857059
	temp = strtoll(str, &end, base?base:10);
Packit 857059
	if ( ! base && ! ((temp == IB_INT64_MAX || temp == IB_INT64_MIN) && errno)
Packit 857059
		&& (end && temp == 0 && *end == 'x' && end != str)) {
Packit 857059
		// try again as base 16
Packit 857059
		temp = strtoll(str, &end, 16);
Packit 857059
	}
Packit 857059
	if (((temp == IB_INT64_MAX || temp == IB_INT64_MIN) && errno)
Packit 857059
		|| (end && end == str)) {
Packit 857059
		if (errno == ERANGE)
Packit 857059
			return FINVALID_SETTING;
Packit 857059
		else
Packit 857059
			return FERROR;
Packit 857059
	}
Packit 857059
Packit 857059
	// skip whitespace
Packit 857059
	if (end && skip_trail_whitespace) {
Packit 857059
		while (isspace(*end)) {
Packit 857059
			end++;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	if (endptr)
Packit 857059
		*endptr = end;
Packit 857059
	else if (end && *end != '\0')
Packit 857059
		return FERROR;
Packit 857059
	*value = temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
FSTATUS StringToInt32(int32 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	int64 temp;
Packit 857059
	FSTATUS status;
Packit 857059
Packit 857059
	status = StringToInt64(&temp, str, endptr, base, skip_trail_whitespace);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if (temp < IB_INT32_MIN || temp > IB_INT32_MAX)
Packit 857059
		return FINVALID_SETTING;
Packit 857059
	*value = (int32)temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
FSTATUS StringToInt16(int16 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	int64 temp;
Packit 857059
	FSTATUS status;
Packit 857059
Packit 857059
	status = StringToInt64(&temp, str, endptr, base, skip_trail_whitespace);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if (temp < IB_INT16_MIN || temp > IB_INT16_MAX)
Packit 857059
		return FINVALID_SETTING;
Packit 857059
	*value = (int16)temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
FSTATUS StringToInt8(int8 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	int64 temp;
Packit 857059
	FSTATUS status;
Packit 857059
Packit 857059
	status = StringToInt64(&temp, str, endptr, base, skip_trail_whitespace);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if (temp < IB_INT8_MIN || temp > IB_INT8_MAX)
Packit 857059
		return FINVALID_SETTING;
Packit 857059
	*value = (int8)temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
// GID of form hValue:lValue
Packit 857059
// values must be base 16, as such 0x prefix is optional for both hValue and
Packit 857059
// lValue
Packit 857059
// whitespace is permitted before and after :
Packit 857059
FSTATUS StringToGid(uint64 *hValue, uint64 *lValue, const char* str, char **endptr, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	FSTATUS status;
Packit 857059
	char *end;
Packit 857059
Packit 857059
	status = StringToUint64(hValue, str, &end, 16, TRUE);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if (end == NULL  || *end != ':')
Packit 857059
		return FERROR;
Packit 857059
	end++;
Packit 857059
	return StringToUint64(lValue, end, endptr, 16, skip_trail_whitespace);
Packit 857059
}
Packit 857059
Packit 857059
// VESWPort of form guid:port:index or desc:port:index
Packit 857059
// guid must be base 16, as such 0x prefix is optional.
Packit 857059
// desc max size is MAX_VFABRIC_NAME (64)
Packit 857059
// port and index are decimal
Packit 857059
// whitespace is permitted before and after :
Packit 857059
// byname = 0: the format is guid:port:index
Packit 857059
// byname = 1: the format is desc:port:index
Packit 857059
FSTATUS StringToVeswPort(uint64 *guid, char *desc, uint32 *port, uint32 *index,
Packit 857059
	const char* str, char **endptr, boolean skip_trail_whitespace,
Packit 857059
	boolean byname)
Packit 857059
{
Packit 857059
	FSTATUS status = FSUCCESS;
Packit 857059
	char *end, *string = NULL;
Packit 857059
	char *name;
Packit 857059
Packit 857059
	if (byname) {
Packit 857059
		string = strdup(str);
Packit 857059
Packit 857059
		name = strtok_r((char *)string, ":", &end;;
Packit 857059
		if (name != NULL && strlen(name) <= MAX_VFABRIC_NAME && end != NULL) {
Packit 857059
			strcpy(desc, name);
Packit 857059
		} else {
Packit 857059
			status = FERROR;
Packit 857059
			goto out;
Packit 857059
		}
Packit 857059
	} else {
Packit 857059
		status = StringToUint64(guid, str, &end, 16, TRUE);
Packit 857059
		if (status != FSUCCESS || end == NULL || *end != ':') {
Packit 857059
			status = FERROR;
Packit 857059
			goto out;
Packit 857059
		}
Packit 857059
		end++;
Packit 857059
	}
Packit 857059
Packit 857059
	status = StringToUint32(port, end, &end, 10, TRUE);
Packit 857059
	if (status != FSUCCESS || end == NULL || *end != ':') {
Packit 857059
		status = FERROR;
Packit 857059
		goto out;
Packit 857059
	}
Packit 857059
	end++;
Packit 857059
	status = StringToUint32(index, end, endptr, 10, skip_trail_whitespace);
Packit 857059
out:
Packit 857059
	if (string != NULL) {
Packit 857059
		free(string);
Packit 857059
	}
Packit 857059
	return status;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
// MAC Address of form %02x:%02x:%02x:%02x:%02x:%02x
Packit 857059
// values must be base16, 0x prefix is optional
Packit 857059
FSTATUS StringToMAC(uint8_t *MAC,const char *str, char **endptr,
Packit 857059
					boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	FSTATUS status;
Packit 857059
	char *end = NULL;
Packit 857059
Packit 857059
	status = StringToUint8(&MAC[0], str, &end, 16, FALSE);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if ((end == NULL) || (*end != ':'))
Packit 857059
		return FERROR;
Packit 857059
	end++;
Packit 857059
Packit 857059
	status = StringToUint8(&MAC[1], end, &end, 16, FALSE);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if ((end == NULL) || (*end != ':'))
Packit 857059
		return FERROR;
Packit 857059
	end++;
Packit 857059
Packit 857059
	status = StringToUint8(&MAC[2], end, &end, 16, FALSE);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if ((end == NULL) || (*end != ':'))
Packit 857059
		return FERROR;
Packit 857059
	end++;
Packit 857059
Packit 857059
	status = StringToUint8(&MAC[3], end, &end, 16, FALSE);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if ((end == NULL) || (*end != ':'))
Packit 857059
		return FERROR;
Packit 857059
	end++;
Packit 857059
Packit 857059
	status = StringToUint8(&MAC[4], end, &end, 16, FALSE);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if ((end == NULL) || (*end != ':'))
Packit 857059
		return FERROR;
Packit 857059
	end++;
Packit 857059
Packit 857059
	status = StringToUint8(&MAC[5], end, endptr, 16, FALSE);
Packit 857059
Packit 857059
	return status;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
// Byte Count as an integer followed by an optional suffix of:
Packit 857059
// K, KB, M, MB, G or GB
Packit 857059
// (K==KB, etc)
Packit 857059
// converted to an absolute number of bytes
Packit 857059
FSTATUS StringToUint64Bytes(uint64 *value, const char* str, char **endptr, int base, boolean skip_trail_whitespace)
Packit 857059
{
Packit 857059
	char *end;
Packit 857059
	FSTATUS status;
Packit 857059
	uint64 temp;
Packit 857059
Packit 857059
	status = StringToUint64(&temp, str, &end, base, skip_trail_whitespace);
Packit 857059
	if (status != FSUCCESS)
Packit 857059
		return status;
Packit 857059
	if (end) {
Packit 857059
		char *units = end;
Packit 857059
		// skip whitespace
Packit 857059
		while (isspace(*units)) {
Packit 857059
			units++;
Packit 857059
		}
Packit 857059
		// parse optional units
Packit 857059
		if (strncmp(units, "KB",2) == 0) {
Packit 857059
			temp *= 1024;
Packit 857059
			end = units+2;
Packit 857059
		} else if (strncmp(units, "K",1) == 0) {
Packit 857059
			temp *= 1024;
Packit 857059
			end = units+1;
Packit 857059
		} else if (strncmp(units, "MB",2) == 0) {
Packit 857059
			temp *= 1024*1024;
Packit 857059
			end = units+2;
Packit 857059
		} else if (strncmp(units, "M",1) == 0) {
Packit 857059
			temp *= 1024*1024;
Packit 857059
			end = units+1;
Packit 857059
		} else if (strncmp(units, "GB",2) == 0) {
Packit 857059
			temp *= (1024*1024*1024ULL);
Packit 857059
			end = units+2;
Packit 857059
		} else if (strncmp(units, "G",1) == 0) {
Packit 857059
			temp *= (1024*1024*1024ULL);
Packit 857059
			end = units+1;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	
Packit 857059
	// skip whitespace
Packit 857059
	if (end && skip_trail_whitespace) {
Packit 857059
		while (isspace(*end)) {
Packit 857059
			end++;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	if (endptr)
Packit 857059
		*endptr = end;
Packit 857059
	else if (end && *end != '\0')
Packit 857059
		return FERROR;
Packit 857059
	*value = temp;
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
#if !defined(VXWORKS)
Packit 857059
#define RELATIVE_TIME_STR_LEN 3
Packit 857059
                                                     // June 6th, 2015 11:59:59 PM
Packit 857059
													 // as represented by the format
Packit 857059
static const char * date_formats[] = {"%Y-%m-%d %T", // 2015-06-30 23:59:59
Packit 857059
                                      "%Y-%m-%d %R", // 2015-06-30 23:59
Packit 857059
                                      "%Y-%m-%d",    // 2015-06-30
Packit 857059
                                      "%m/%d/%Y %T", // 06/30/2015 23:59:59
Packit 857059
                                      "%m/%d/%Y %R", // 06/30/2015 23:59
Packit 857059
                                      "%m/%d/%Y",    // 06/30/2015
Packit 857059
                                      "%d.%m.%Y %T", // 30.06.2015 23:59:59
Packit 857059
                                      "%d.%m.%Y %R", // 30.06.2015 23:59
Packit 857059
                                      "%d.%m.%Y",    // 30.06.2015
Packit 857059
                                                     // %x, %X are locale specific
Packit 857059
                                      "%x %X",       // e.g. 30/06/15 23:59:59 or 30.06.2015 23.59.59, etc.
Packit 857059
                                      "%x",          // e.g. 30/06/15, 06/30/15, etc.
Packit 857059
                                      "%X",          // e.g. 23:59:59, 23.59.59, etc.
Packit 857059
                                      "%R"};         // 23:59
Packit 857059
static const char * time_units[] = {"seconds", "minutes", "hours", "days"};
Packit 857059
Packit 857059
/**
Packit 857059
 * StringToDateTime - parse a string to return a date/time
Packit 857059
 *
Packit 857059
 * @param value  - will contain date as # of seconds since epoch if parsing successful
Packit 857059
 * @param str    - the string representation of the date to be parsed
Packit 857059
 *
Packit 857059
 * @return - FSTATUS indicating success or failure of parsing:
Packit 857059
 * 			 FSUCCESS - successful parsing
Packit 857059
 * 			 FINVALID_PARAMETER - str not valid date/time or not in valid format
Packit 857059
 * 			 FINVALID_SETTING - relative value out of range
Packit 857059
 * 			 FINSUFFICIENT_MEMORY - memory could not be allocated to parse string
Packit 857059
 * 			 FERROR - other error parsing string
Packit 857059
 */
Packit 857059
FSTATUS StringToDateTime(uint32 *value, const char* str){
Packit 857059
	int i, len;
Packit 857059
	char * return_str;
Packit 857059
	struct tm tm = {0};
Packit 857059
	uint32 seconds;
Packit 857059
	FSTATUS status;
Packit 857059
Packit 857059
	//try to match input to one of known formats from above
Packit 857059
	len = sizeof(date_formats) / sizeof(const char *);
Packit 857059
	for (i = 0; i < len; ++i){
Packit 857059
		memset(&tm, 0, sizeof(struct tm));
Packit 857059
		return_str = strptime(str, date_formats[i], &tm;;
Packit 857059
		// want to match an exact format, meaning strptime returns null byte
Packit 857059
		if (return_str != NULL && *return_str == '\0'){
Packit 857059
			break;
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	if (return_str != NULL && *return_str== '\0'){ // possible valid date entered
Packit 857059
		struct tm tm2;
Packit 857059
		time_t timer;
Packit 857059
		if (i >= len - 2){
Packit 857059
			// strptime matched against %X or %R, meaning we have a time
Packit 857059
			// but no information on the date. Fill in tm with today's date
Packit 857059
			time(&timer;;   //get current time
Packit 857059
			struct tm * tmp;
Packit 857059
			tmp = localtime(&timer;;
Packit 857059
			if (!tmp){
Packit 857059
				return FERROR;
Packit 857059
			}
Packit 857059
			tm.tm_year = tmp->tm_year;
Packit 857059
			tm.tm_mon = tmp->tm_mon;
Packit 857059
			tm.tm_mday = tmp->tm_mday;
Packit 857059
			tm.tm_wday = tmp->tm_wday;
Packit 857059
			tm.tm_yday = tmp->tm_yday;
Packit 857059
		}
Packit 857059
		// mktime will normalize fields of tm if they are outside their valid range,
Packit 857059
		// so make a copy before the mktime call and compare before and after. If the
Packit 857059
		// days of the month are not equal then the date enetered was not valid
Packit 857059
		memcpy(&tm2, &tm, sizeof(struct tm));
Packit 857059
		tm.tm_isdst = -1; //signal mktime to determine if daylight saving in effect
Packit 857059
		timer = mktime(&tm;;
Packit 857059
		if (timer != -1){
Packit 857059
			//check if input time was a valid date, e.g. not 02/30/YYYY
Packit 857059
			if (tm.tm_mday != tm2.tm_mday){
Packit 857059
				return FINVALID_PARAMETER;
Packit 857059
			}else{
Packit 857059
				*value = (uint32) timer;
Packit 857059
				return FSUCCESS;
Packit 857059
			}
Packit 857059
		}
Packit 857059
	}else{
Packit 857059
		// determine if time entered in the form
Packit 857059
		// "<x> <units> ago" where units is a member of time_units from above
Packit 857059
		char *string, *saveptr, *token, *tokens[RELATIVE_TIME_STR_LEN];
Packit 857059
Packit 857059
		string = strdup(str);
Packit 857059
		if (!string){
Packit 857059
			return FINSUFFICIENT_MEMORY;
Packit 857059
		}
Packit 857059
Packit 857059
		//split string by space (" ")
Packit 857059
		token = strtok_r(string, " ", &saveptr);
Packit 857059
		i = 0;
Packit 857059
		while (token != NULL){
Packit 857059
			if (i >= RELATIVE_TIME_STR_LEN){
Packit 857059
				//too many tokens
Packit 857059
				free(string);
Packit 857059
				return FERROR;
Packit 857059
			}
Packit 857059
			tokens[i] = token;
Packit 857059
			++i;
Packit 857059
			token = strtok_r(NULL, " ", &saveptr);
Packit 857059
		}
Packit 857059
Packit 857059
		//check if proper number of tokens
Packit 857059
		if (i != RELATIVE_TIME_STR_LEN){
Packit 857059
			free(string);
Packit 857059
			return FINVALID_PARAMETER;
Packit 857059
		}
Packit 857059
Packit 857059
		//check if first token is a valid base 10 number
Packit 857059
		status = StringToUint32(&seconds, tokens[0], NULL, 10, TRUE);
Packit 857059
		if (FSUCCESS != status){
Packit 857059
			free(string);
Packit 857059
			return status;
Packit 857059
		}
Packit 857059
Packit 857059
		//check if second token in accepted units of time
Packit 857059
		len = sizeof(time_units) / sizeof (const char *);
Packit 857059
		for (i = 0; i < len; ++i){
Packit 857059
			if (strcasecmp(time_units[i], tokens[1]) == 0 || strncasecmp(time_units[i], tokens[1], strlen(time_units[i]) - 1) == 0){
Packit 857059
				break;
Packit 857059
			}
Packit 857059
		}
Packit 857059
Packit 857059
		//convert first token to seconds if necessary
Packit 857059
		if (i >= len){
Packit 857059
			// could not determine units
Packit 857059
			free(string);
Packit 857059
			return FERROR;
Packit 857059
		}
Packit 857059
Packit 857059
		switch (i){
Packit 857059
		case 0:
Packit 857059
			break;
Packit 857059
		case 1: //convert from minutes to seconds
Packit 857059
			seconds = seconds * 60;
Packit 857059
			break;
Packit 857059
		case 2: //convert from hours to seconds
Packit 857059
			seconds = seconds * 60 * 60;
Packit 857059
			break;
Packit 857059
		case 3: //convert from days to seconds
Packit 857059
			seconds = seconds * 24 * 60 * 60;
Packit 857059
		}
Packit 857059
Packit 857059
		//calculate absolute time to query for
Packit 857059
		time_t timer;
Packit 857059
		time(&timer;;
Packit 857059
		*value = (uint32)timer - seconds;
Packit 857059
Packit 857059
		free(string);
Packit 857059
		return FSUCCESS;
Packit 857059
	}
Packit 857059
Packit 857059
	return FERROR;
Packit 857059
}
Packit 857059
Packit 857059
// Tuple of form select:comparator:argument
Packit 857059
// select must be one of "utilization", "pktrate", "integrity", "congestion", "smacongestion", "bubbles", "security", or "routing".
Packit 857059
// comparator must be one of "GT", "LT", "GE", "LE".
Packit 857059
// argument may be any 64-bit value
Packit 857059
// string inputs are case insensitive.
Packit 857059
FSTATUS StringToTuple(uint32 *select, uint8 *comparator, uint64 *argument, char* str, char **endptr)
Packit 857059
{
Packit 857059
	FSTATUS status = FSUCCESS;
Packit 857059
	char *end;
Packit 857059
	char *selectstr;
Packit 857059
	char *comparatorstr;
Packit 857059
	char *argumentstr;
Packit 857059
Packit 857059
	if ((select == NULL) || (comparator == NULL) || (argument == NULL) || (str == NULL))
Packit 857059
		return FERROR;
Packit 857059
Packit 857059
	selectstr = strtok_r(str, ":", &end;;
Packit 857059
Packit 857059
	if (selectstr == NULL)
Packit 857059
		return FERROR;
Packit 857059
Packit 857059
	if (strcasecmp(selectstr, "utilization") == 0)
Packit 857059
		*select = STL_PA_SELECT_UTIL_HIGH;
Packit 857059
	else if (strcasecmp(selectstr, "pktrate") == 0)
Packit 857059
		*select = STL_PA_SELECT_UTIL_PKTS_HIGH;
Packit 857059
	else if (strcasecmp(selectstr, "integrity") == 0)
Packit 857059
		*select = STL_PA_SELECT_CATEGORY_INTEG;
Packit 857059
	else if (strcasecmp(selectstr, "congestion") == 0)
Packit 857059
		*select = STL_PA_SELECT_CATEGORY_CONG;
Packit 857059
	else if (strcasecmp(selectstr, "smacongestion") == 0)
Packit 857059
		*select = STL_PA_SELECT_CATEGORY_SMA_CONG;
Packit 857059
	else if (strcasecmp(selectstr, "bubbles") == 0)
Packit 857059
		*select = STL_PA_SELECT_CATEGORY_BUBBLE;
Packit 857059
	else if (strcasecmp(selectstr, "security") == 0)
Packit 857059
		*select = STL_PA_SELECT_CATEGORY_SEC;
Packit 857059
	else if (strcasecmp(selectstr, "routing") == 0)
Packit 857059
		*select = STL_PA_SELECT_CATEGORY_ROUT;
Packit 857059
	else
Packit 857059
		return FERROR;
Packit 857059
Packit 857059
	comparatorstr = strtok_r((char *)NULL, ":", &end;;
Packit 857059
Packit 857059
	if (comparatorstr == NULL)
Packit 857059
		return FERROR;
Packit 857059
Packit 857059
	if (strcasecmp(comparatorstr, "GT") == 0)
Packit 857059
		*comparator = FOCUS_PORTS_COMPARATOR_GREATER_THAN;
Packit 857059
	else if (strcasecmp(comparatorstr, "LT") == 0)
Packit 857059
		*comparator = FOCUS_PORTS_COMPARATOR_LESS_THAN;
Packit 857059
	else if (strcasecmp(comparatorstr, "GE") == 0)
Packit 857059
		*comparator = FOCUS_PORTS_COMPARATOR_GREATER_THAN_OR_EQUAL;
Packit 857059
	else if (strcasecmp(comparatorstr, "LE") == 0)
Packit 857059
		*comparator = FOCUS_PORTS_COMPARATOR_LESS_THAN_OR_EQUAL;
Packit 857059
	else
Packit 857059
		return FERROR;
Packit 857059
Packit 857059
	argumentstr = strtok_r((char *)NULL, ":", &end;;
Packit 857059
Packit 857059
	if (argumentstr) {
Packit 857059
		status = StringToUint64(argument, argumentstr, NULL, 0, TRUE);
Packit 857059
		return status;
Packit 857059
	}
Packit 857059
Packit 857059
	return FERROR;
Packit 857059
}
Packit 857059
Packit 857059
#endif
Packit 857059
Packit 857059
#if !defined(VXWORKS)
Packit 857059
#define MEMORY_ALLOCATE_PRIV(size, flags, tag) MemoryAllocatePriv(size, flags, tag)
Packit 857059
#define MEMORY_ALLOCATE_PHYS_CONT_PRIV(size) MemoryAllocatePhysContPriv(size)
Packit 857059
#define MEMORY_DEALLOCATE_PHYS_CONT_PRIV(size) MemoryDeallocatePhysContPriv(size)
Packit 857059
#define MEMORY_DEALLOCATE_PRIV(ptr) MemoryDeallocatePriv(ptr)
Packit 857059
#else
Packit 857059
#define MEMORY_ALLOCATE_PRIV(size, flags, tag) MemoryAllocatePriv(size, __builtin_return_address(0))
Packit 857059
#define MEMORY_ALLOCATE_PHYS_CONT_PRIV(size) MemoryAllocatePhysContPriv(size, __builtin_return_address(0))
Packit 857059
#define MEMORY_DEALLOCATE_PHYS_CONT_PRIV(size) MemoryDeallocatePhysContPriv(size, __builtin_return_address(0))
Packit 857059
#define MEMORY_DEALLOCATE_PRIV(ptr) MemoryDeallocatePriv(ptr, __builtin_return_address(0))
Packit 857059
#endif
Packit 857059
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
//
Packit 857059
// Destroy the memory tracker object.
Packit 857059
//
Packit 857059
static __inline void
Packit 857059
DestroyMemTracker( void )
Packit 857059
{
Packit 857059
	MEM_TRACKER *tmp;
Packit 857059
	if( !pMemTracker )
Packit 857059
		return;
Packit 857059
Packit 857059
	tmp = pMemTracker;
Packit 857059
	pMemTracker = NULL; /* so no one uses it while we're destroying it */
Packit 857059
Packit 857059
	// Destory all objects in the memory tracker object.
Packit 857059
	QListDestroy( &tmp->FreeHrdList );
Packit 857059
	SpinLockDestroy( &tmp->Lock );
Packit 857059
	QListDestroy( &tmp->AllocList );
Packit 857059
Packit 857059
	// Free the memory allocated for the memory tracker object.
Packit 857059
	MEMORY_DEALLOCATE_PRIV( tmp );
Packit 857059
}
Packit 857059
Packit 857059
//
Packit 857059
// Allocate and initialize the memory tracker object.
Packit 857059
//
Packit 857059
static __inline boolean
Packit 857059
CreateMemTracker( void )
Packit 857059
{
Packit 857059
	MEM_TRACKER *tmp;
Packit 857059
Packit 857059
	if( pMemTracker )
Packit 857059
		return TRUE;
Packit 857059
Packit 857059
	// Allocate the memory tracker object. Don't update global until we're done
Packit 857059
	tmp = (MEM_TRACKER*)MEMORY_ALLOCATE_PRIV( sizeof(MEM_TRACKER), IBA_MEM_FLAG_LEGACY, TRK_TAG );
Packit 857059
Packit 857059
	if( !tmp )
Packit 857059
		return FALSE;
Packit 857059
Packit 857059
	// Pre-initialize all objects in the memory tracker object.
Packit 857059
	QListInitState( &tmp->AllocList );
Packit 857059
	SpinLockInitState( &tmp->Lock );
Packit 857059
	QListInitState( &tmp->FreeHrdList );
Packit 857059
Packit 857059
	// Initialize the list.
Packit 857059
	if( !QListInit( &tmp->AllocList ) )
Packit 857059
	{
Packit 857059
		/* global isn't initialize, don't call Destroy func; do the clean up */
Packit 857059
		MEMORY_DEALLOCATE_PRIV( tmp );
Packit 857059
		return FALSE;
Packit 857059
	}
Packit 857059
Packit 857059
	// Initialize the spin lock to protect list operations.
Packit 857059
	if( !SpinLockInit( &tmp->Lock ) )
Packit 857059
	{
Packit 857059
		/* global isn't initialize, don't call Destroy func; do the clean up */
Packit 857059
		QListDestroy( &tmp->AllocList );
Packit 857059
		SpinLockDestroy( &tmp->Lock );
Packit 857059
		MEMORY_DEALLOCATE_PRIV( tmp );
Packit 857059
		return FALSE;
Packit 857059
	}
Packit 857059
Packit 857059
	// Initialize the free list.
Packit 857059
	if( !QListInit( &tmp->FreeHrdList ) )
Packit 857059
	{
Packit 857059
		/* global isn't initialize, don't call Destroy func; do the clean up */
Packit 857059
		QListDestroy( &tmp->AllocList );
Packit 857059
		SpinLockDestroy( &tmp->Lock );
Packit 857059
		MEMORY_DEALLOCATE_PRIV( tmp );
Packit 857059
		return FALSE;
Packit 857059
	}
Packit 857059
Packit 857059
//	MsgOut( "\n\n\n*** Memory tracker object address = %p ***\n\n\n", tmp );
Packit 857059
	MsgOut( "\n*** Memory tracker enabled ***\n" );
Packit 857059
Packit 857059
	/* NOW update the global */
Packit 857059
	pMemTracker = tmp;
Packit 857059
Packit 857059
	return TRUE;
Packit 857059
}
Packit 857059
#endif
Packit 857059
Packit 857059
//
Packit 857059
// Enables memory allocation tracking.
Packit 857059
//
Packit 857059
static __inline void
Packit 857059
MemoryTrackStart( void )
Packit 857059
{
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
	if( pMemTracker )
Packit 857059
		return;
Packit 857059
Packit 857059
	CreateMemTracker();
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
//
Packit 857059
// Clean up memory tracking.
Packit 857059
//
Packit 857059
static __inline void
Packit 857059
MemoryTrackStop( void )
Packit 857059
{
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
	LIST_ITEM	*pListItem;
Packit 857059
Packit 857059
	if( !pMemTracker )
Packit 857059
		return;
Packit 857059
Packit 857059
	if( QListCount( &pMemTracker->AllocList ) )
Packit 857059
	{
Packit 857059
		// There are still items in the list.  Print them out.
Packit 857059
		MemoryDisplayUsage(1, 0, 0);
Packit 857059
	} else {
Packit 857059
		MsgOut( "\n*** Memory tracker stopped, no leaks detected ***\n" );
Packit 857059
		MsgOut("IbAccess max allocations=%u bytes=%u\n",
Packit 857059
						max_allocations, max_allocated);
Packit 857059
	}
Packit 857059
Packit 857059
	// Free all allocated headers.
Packit 857059
	SpinLockAcquire( &pMemTracker->Lock );
Packit 857059
	while( (pListItem = QListRemoveHead( &pMemTracker->AllocList )) != NULL )
Packit 857059
	{
Packit 857059
		SpinLockRelease( &pMemTracker->Lock );
Packit 857059
		MEMORY_DEALLOCATE_PRIV( PARENT_STRUCT( pListItem, MEM_ALLOC_HDR, ListItem ) );
Packit 857059
		SpinLockAcquire( &pMemTracker->Lock );
Packit 857059
	}
Packit 857059
	while( (pListItem = QListRemoveHead( &pMemTracker->FreeHrdList )) != NULL )
Packit 857059
	{
Packit 857059
		SpinLockRelease( &pMemTracker->Lock );
Packit 857059
		MEMORY_DEALLOCATE_PRIV( PARENT_STRUCT( pListItem, MEM_ALLOC_HDR, ListItem ) );
Packit 857059
		SpinLockAcquire( &pMemTracker->Lock );
Packit 857059
	}
Packit 857059
	SpinLockRelease( &pMemTracker->Lock );
Packit 857059
Packit 857059
	DestroyMemTracker();
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
//
Packit 857059
// Enables memory allocation tracking.
Packit 857059
//
Packit 857059
void
Packit 857059
MemoryTrackUsage( 
Packit 857059
	IN boolean Start )
Packit 857059
{
Packit 857059
	if( Start )
Packit 857059
		MemoryTrackStart();
Packit 857059
	else
Packit 857059
		MemoryTrackStop();
Packit 857059
}
Packit 857059
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
static void
Packit 857059
MemoryTrackerShow(
Packit 857059
		IN char *prefix, 
Packit 857059
		IN MEM_ALLOC_HDR	*pHdr,
Packit 857059
		IN char *suffix)
Packit 857059
{
Packit 857059
#if defined(VXWORKS)
Packit 857059
	if ((int)pHdr->LineNum >= 0x00408000) {
Packit 857059
		MsgOut( "%s%p(%u) %s ra=%p tick=%u%s\n", prefix,
Packit 857059
				pHdr->ListItem.pObject, pHdr->Bytes, pHdr->trk->filename,
Packit 857059
				(void *)pHdr->LineNum, pHdr->tick, suffix );
Packit 857059
	} else 
Packit 857059
		MsgOut( "%s%p(%u) in file %s line %d tick=%u%s\n", prefix,
Packit 857059
				pHdr->ListItem.pObject, pHdr->Bytes, pHdr->trk->filename,
Packit 857059
				pHdr->LineNum, pHdr->tick, suffix );
Packit 857059
#else
Packit 857059
		MsgOut( "%s%p(%u) in file %s line %d%s\n", prefix,
Packit 857059
				pHdr->ListItem.pObject, pHdr->Bytes, pHdr->trk->filename,
Packit 857059
				pHdr->LineNum, suffix );
Packit 857059
#endif
Packit 857059
}
Packit 857059
Packit 857059
static void
Packit 857059
MemoryTrackerCheckOverrun(
Packit 857059
		IN MEM_ALLOC_HDR	*pHdr )
Packit 857059
{
Packit 857059
#ifdef MEM_TRACK_FTR
Packit 857059
	// Check that the user did not overrun his memory allocation.
Packit 857059
	if( (pHdr->pFtr != NULL) && (pHdr->pFtr->OutOfBound != TRK_TAG) )
Packit 857059
	{
Packit 857059
		MemoryTrackerShow("*** User overrun detected ", pHdr, "");
Packit 857059
	}
Packit 857059
#endif
Packit 857059
}
Packit 857059
Packit 857059
/* unlink a header from the allocated list */
Packit 857059
/* must be called with pMemTracker->Lock held */
Packit 857059
static void
Packit 857059
MemoryTrackerUnlink(
Packit 857059
		IN MEM_ALLOC_HDR	*pHdr )
Packit 857059
{
Packit 857059
	// Remove the item from the list.
Packit 857059
	QListRemoveItem( &pMemTracker->AllocList, &pHdr->ListItem );
Packit 857059
Packit 857059
	--current_allocations;
Packit 857059
	current_allocated -= pHdr->Bytes;
Packit 857059
	if (pHdr->reported)
Packit 857059
		MemoryTrackerShow("", pHdr, " FREED");
Packit 857059
	MemoryTrackerDereference(pHdr->trk);
Packit 857059
	// Return the header to the free header list.
Packit 857059
	QListInsertHead( &pMemTracker->FreeHrdList, &pHdr->ListItem );
Packit 857059
}
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
Packit 857059
//
Packit 857059
// Display memory usage.
Packit 857059
//
Packit 857059
void
Packit 857059
MemoryDisplayUsage( int method, uint32 minSize, uint32 minTick )
Packit 857059
{
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
	uint32 allocated = 0;
Packit 857059
	uint32 allocations = 0;
Packit 857059
	MEM_ALLOC_HDR	*pHdr;
Packit 857059
	LIST_ITEM *item, *next, *tail, *head;
Packit 857059
	unsigned int allocations_per_sec = 0;
Packit 857059
	uint32 currentTime;
Packit 857059
	boolean all = (method == 1);
Packit 857059
Packit 857059
	if( !pMemTracker ) {
Packit 857059
		MsgOut( "*** IbAccess Memory Tracking is disabled ***\n" );
Packit 857059
		return;
Packit 857059
	}
Packit 857059
Packit 857059
	/* "lock" present allocations by setting
Packit 857059
	 * displaying flag, so other allocates/frees will not affect them
Packit 857059
	 * This gives us a snapshot while permitting the system to run
Packit 857059
	 * while we perform the output (the output itself may use memory allocate)
Packit 857059
	 * However, our report loop below must stay within head/tail
Packit 857059
	 */
Packit 857059
	SpinLockAcquire( &pMemTracker->Lock );
Packit 857059
	tail = QListTail(&pMemTracker->AllocList);
Packit 857059
	head = QListHead(&pMemTracker->AllocList);
Packit 857059
	for(item = head; item != NULL; item = QListNext(&pMemTracker->AllocList, item)) {
Packit 857059
		pHdr = PARENT_STRUCT( item, MEM_ALLOC_HDR, ListItem );
Packit 857059
		pHdr->displaying = TRUE;
Packit 857059
	}
Packit 857059
	SpinLockRelease (&pMemTracker->Lock);
Packit 857059
	
Packit 857059
	MsgOut( "*** IbAccess Memory Usage %s minSize=%d minTick=%d ***\n", all?"All":"Unreported", minSize, minTick );
Packit 857059
Packit 857059
	if (head && tail) {
Packit 857059
		item = head;
Packit 857059
		do {
Packit 857059
			next = QListNext(&pMemTracker->AllocList, item);
Packit 857059
			pHdr = PARENT_STRUCT( item, MEM_ALLOC_HDR, ListItem );
Packit 857059
	
Packit 857059
	#ifdef MEM_TRACK_FTR
Packit 857059
			// Check that the user did not overrun his memory allocation.
Packit 857059
			if (pHdr->deallocate == FALSE) {
Packit 857059
				MemoryTrackerCheckOverrun(pHdr);
Packit 857059
			}
Packit 857059
	#endif	// MEM_TRACK_FTR
Packit 857059
			if ((pHdr->Bytes >= minSize) && (pHdr->tick >= minTick) && (all || (pHdr->reported == 0))) {
Packit 857059
				// method 2 just marks all current allocations as reported, without actually reporting them
Packit 857059
				// method 3 displays the items without changing their reported state (allows us to avoid the FREED messages)
Packit 857059
				if (method != 2)
Packit 857059
					MemoryTrackerShow("", pHdr, "");
Packit 857059
				if (method != 3)
Packit 857059
					pHdr->reported = 1;
Packit 857059
			}
Packit 857059
			allocated += pHdr->Bytes;
Packit 857059
			++allocations;
Packit 857059
			SpinLockAcquire( &pMemTracker->Lock );
Packit 857059
			pHdr->displaying = FALSE;
Packit 857059
			if (pHdr->deallocate) {
Packit 857059
				MemoryTrackerUnlink(pHdr);
Packit 857059
			}
Packit 857059
			SpinLockRelease (&pMemTracker->Lock);
Packit 857059
			item = next;
Packit 857059
		} while (&pHdr->ListItem != tail && item != NULL);
Packit 857059
	}
Packit 857059
	currentTime = GetTimeStampSec();
Packit 857059
	if (last_reported_secs && currentTime != last_reported_secs) {
Packit 857059
		allocations_per_sec = (total_allocations - last_reported_allocations) / (currentTime - last_reported_secs);
Packit 857059
	}
Packit 857059
	last_reported_secs = currentTime;
Packit 857059
	last_reported_allocations = total_allocations;
Packit 857059
	MsgOut("IbAccess current allocations=%u bytes=%u max allocations=%u bytes=%u p/s=%d\n",
Packit 857059
			allocations, allocated, max_allocations, max_allocated, allocations_per_sec);
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
unsigned int hashValue(const char *key) {
Packit 857059
	unsigned int  nHash = 0;
Packit 857059
	while (*key)
Packit 857059
		nHash = (nHash<<5) + nHash + *key++;
Packit 857059
	return nHash;
Packit 857059
}
Packit 857059
Packit 857059
static MemoryTrackerFileName_t *MemoryTrackerFileNameLookup(const char *filename, unsigned int *hash) {
Packit 857059
	unsigned int hashVal;
Packit 857059
	MemoryTrackerFileName_t *trk;
Packit 857059
	int len = strlen(filename);
Packit 857059
Packit 857059
	hashVal = hashValue(filename) % MEMORY_TRACKER_BUCKETS;
Packit 857059
	*hash = hashVal;
Packit 857059
Packit 857059
	for(trk = MemoryTrackerBuckets[hashVal]; trk != NULL; trk = trk->next) {
Packit 857059
		if (trk->filenameLen == len) {
Packit 857059
			if (memcmp(&trk->filename[0], filename, len) == 0) {
Packit 857059
				return trk;
Packit 857059
			}
Packit 857059
		}
Packit 857059
	}
Packit 857059
	return NULL;
Packit 857059
}
Packit 857059
Packit 857059
static MemoryTrackerFileName_t *MemoryTrackerFileNameAlloc(const char *filename, int filenameLen, unsigned int hash) {
Packit 857059
	MemoryTrackerFileName_t *trk;
Packit 857059
Packit 857059
	trk = (MemoryTrackerFileName_t*)MEMORY_ALLOCATE_PRIV(
Packit 857059
					 	sizeof( MemoryTrackerFileName_t ) + filenameLen + 1,
Packit 857059
						IBA_MEM_FLAG_LEGACY, TRK_TAG );
Packit 857059
	if (trk != NULL) {
Packit 857059
		trk->referenceCount = 1;
Packit 857059
		trk->filenameLen = filenameLen;
Packit 857059
		memcpy(&trk->filename, filename, filenameLen + 1);
Packit 857059
		trk->next = MemoryTrackerBuckets[hash];
Packit 857059
		MemoryTrackerBuckets[hash] = trk;
Packit 857059
		// MsgOut("Added len=%d name=(%p)%s\n", filenameLen, trk->filename, trk->filename);
Packit 857059
	}
Packit 857059
	return trk;
Packit 857059
}
Packit 857059
Packit 857059
static MemoryTrackerFileName_t *MemoryTrackerReference(const char *filename) {
Packit 857059
	MemoryTrackerFileName_t *trk;
Packit 857059
	int len = strlen(filename);
Packit 857059
	unsigned int hash;
Packit 857059
Packit 857059
	trk = MemoryTrackerFileNameLookup(filename, &hash);
Packit 857059
	if (trk == NULL) {
Packit 857059
		trk = MemoryTrackerFileNameAlloc(filename, len, hash);
Packit 857059
		if (trk == NULL)
Packit 857059
			return NULL;
Packit 857059
	} else {
Packit 857059
		++trk->referenceCount;
Packit 857059
	}
Packit 857059
	return trk;
Packit 857059
}
Packit 857059
Packit 857059
static void MemoryTrackerDereference(MemoryTrackerFileName_t *trk) {
Packit 857059
	if (trk == NULL) {
Packit 857059
		MsgOut("Could not find reference to trk=%p\n", trk);
Packit 857059
	} else {
Packit 857059
		--trk->referenceCount;
Packit 857059
	}
Packit 857059
}
Packit 857059
Packit 857059
static void
Packit 857059
MemoryTrackerTrackAllocation(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine, 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags,
Packit 857059
	IN void *pMem,
Packit 857059
	IN MEM_ALLOC_FTR *pFtr)
Packit 857059
{
Packit 857059
	MEM_ALLOC_HDR	*pHdr;
Packit 857059
	LIST_ITEM		*pListItem;
Packit 857059
Packit 857059
#ifdef MEM_TRACK_FTR
Packit 857059
	if (pFtr)
Packit 857059
		pFtr->OutOfBound = TRK_TAG;
Packit 857059
#endif  // MEM_TRACK_FTR
Packit 857059
Packit 857059
	if( !pMemTracker ) {
Packit 857059
		if (unTindex < UNTRACKED_COUNT)
Packit 857059
			unTAddr[unTindex++] = pMem;
Packit 857059
		else {
Packit 857059
			static int firsttime=1;
Packit 857059
			if (firsttime) {
Packit 857059
				MsgOut("***** Untracked memory allocation array LIMIT:%d REACHED; check unTmissed value to calculate new size\n", UNTRACKED_COUNT);
Packit 857059
				firsttime = 0;
Packit 857059
			}
Packit 857059
			unTmissed++; /* so we know how much more to expand the array */
Packit 857059
		}
Packit 857059
		return;
Packit 857059
	}
Packit 857059
Packit 857059
	// Get a header from the free header list.
Packit 857059
	SpinLockAcquire( &pMemTracker->Lock );
Packit 857059
	pListItem = QListRemoveHead( &pMemTracker->FreeHrdList );
Packit 857059
	SpinLockRelease( &pMemTracker->Lock );
Packit 857059
Packit 857059
	if( pListItem )
Packit 857059
	{
Packit 857059
		// Set the header pointer to the header retrieved from the list.
Packit 857059
		pHdr = PARENT_STRUCT( pListItem, MEM_ALLOC_HDR, ListItem );
Packit 857059
	}
Packit 857059
	else
Packit 857059
	{
Packit 857059
		// We failed to get a free header.  Allocate one.
Packit 857059
		// we can prempt if caller allows it, however we do not want
Packit 857059
		// pageable, nor short duration memory
Packit 857059
		pHdr = (MEM_ALLOC_HDR*)MEMORY_ALLOCATE_PRIV( sizeof( MEM_ALLOC_HDR ),
Packit 857059
								flags & IBA_MEM_FLAG_PREMPTABLE, TRK_TAG );
Packit 857059
		if( !pHdr )
Packit 857059
		{
Packit 857059
			// We failed to allocate the header, don't track this allocate
Packit 857059
			return;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	pHdr->LineNum = nLine;
Packit 857059
	pHdr->tick = TICK;
Packit 857059
	pHdr->Bytes = Bytes;
Packit 857059
	pHdr->reported = 0;
Packit 857059
	pHdr->displaying = FALSE;
Packit 857059
	pHdr->deallocate = FALSE;
Packit 857059
	// We store the pointer to the memory returned to the user.  This allows
Packit 857059
	// searching the list of allocated memory even if the buffer allocated is 
Packit 857059
	// not in the list without dereferencing memory we do not own.
Packit 857059
	pHdr->ListItem.pObject = pMem;
Packit 857059
Packit 857059
#ifdef MEM_TRACK_FTR
Packit 857059
	pHdr->pFtr = pFtr;
Packit 857059
#else
Packit 857059
	pHdr->pFtr = NULL;
Packit 857059
#endif  // MEM_TRACK_FTR
Packit 857059
Packit 857059
	SpinLockAcquire( &pMemTracker->Lock );
Packit 857059
	pHdr->trk = MemoryTrackerReference(pFileName);
Packit 857059
	++total_allocations;
Packit 857059
	if (++current_allocations > max_allocations)
Packit 857059
		max_allocations = current_allocations;
Packit 857059
	if ((current_allocated += pHdr->Bytes) > max_allocated)
Packit 857059
		max_allocated = current_allocated;
Packit 857059
Packit 857059
	// Insert the header structure into our allocation list.
Packit 857059
	QListInsertTail( &pMemTracker->AllocList, &pHdr->ListItem );
Packit 857059
	SpinLockRelease( &pMemTracker->Lock );
Packit 857059
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
int
Packit 857059
MemoryTrackerTrackDeallocate( 
Packit 857059
	IN void *pMemory )
Packit 857059
{
Packit 857059
	MEM_ALLOC_HDR	*pHdr;
Packit 857059
	LIST_ITEM		*pListItem;
Packit 857059
	int				result = 0;
Packit 857059
Packit 857059
	if( pMemTracker )
Packit 857059
	{
Packit 857059
		SpinLockAcquire( &pMemTracker->Lock );
Packit 857059
Packit 857059
		// Removes an item from the allocation tracking list given a pointer
Packit 857059
		// To the user's data and returns the pointer to header referencing the
Packit 857059
		// allocated memory block.
Packit 857059
		pListItem = 
Packit 857059
			QListFindFromTail( &pMemTracker->AllocList, NULL, pMemory );
Packit 857059
Packit 857059
		if( pListItem )
Packit 857059
		{
Packit 857059
			// Get the pointer to the header.
Packit 857059
			pHdr = PARENT_STRUCT( pListItem, MEM_ALLOC_HDR, ListItem );
Packit 857059
#ifdef MEM_TRACK_FTR
Packit 857059
			MemoryTrackerCheckOverrun(pHdr);
Packit 857059
#endif	// MEM_TRACK_FTR
Packit 857059
Packit 857059
			if (pHdr->displaying) {
Packit 857059
				pHdr->deallocate = TRUE;
Packit 857059
			} else {
Packit 857059
				// Remove the item from the list.
Packit 857059
				MemoryTrackerUnlink(pHdr);
Packit 857059
			}
Packit 857059
		} else {
Packit 857059
			int ii, found; 
Packit 857059
			for (ii=0, found=0; ii
Packit 857059
				if (unTAddr[ii] == pMemory) {
Packit 857059
					int nextii = ii+1;
Packit 857059
					/* move up the remaining entries */
Packit 857059
					if (nextii < unTindex) {
Packit 857059
						memcpy(&unTAddr[ii], &unTAddr[nextii], 
Packit 857059
							(unTindex - nextii)*sizeof(void));
Packit 857059
					}
Packit 857059
					/* decrease entry count */
Packit 857059
					unTindex--;
Packit 857059
					/* zero out the new free location */
Packit 857059
					unTAddr[unTindex] = 0;
Packit 857059
					found = 1;
Packit 857059
					break;
Packit 857059
				}
Packit 857059
			}
Packit 857059
			if (!found) {
Packit 857059
				result = 1;
Packit 857059
#if defined(VXWORKS)
Packit 857059
				MsgOut( "UNMATCHED FREE %p ra=%p %p %p\n", pMemory, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2));
Packit 857059
				/* DumpStack fails in to find Osa_SysThread object in Osa_SysThread::FindThread. Until that is fixed skip dumping the stack. */
Packit 857059
#else
Packit 857059
				MsgOut( "BAD FREE %p\n", pMemory);
Packit 857059
				DumpStack();
Packit 857059
#endif
Packit 857059
			}
Packit 857059
		}
Packit 857059
		SpinLockRelease( &pMemTracker->Lock );
Packit 857059
	}
Packit 857059
	return result;
Packit 857059
}
Packit 857059
Packit 857059
//
Packit 857059
// Allocates memory and stores information about the allocation in a list.
Packit 857059
// The contents of the list can be printed out by calling the function
Packit 857059
// "MemoryReportUsage".  Memory allocation will succeed even if the list 
Packit 857059
// cannot be created.
Packit 857059
//
Packit 857059
void*
Packit 857059
MemoryAllocateDbg(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine, 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocate2Dbg(pFileName, nLine, Bytes,
Packit 857059
					(IsPageable?IBA_MEM_FLAG_PAGEABLE:IBA_MEM_FLAG_NONE)
Packit 857059
					|IBA_MEM_FLAG_LEGACY, Tag);
Packit 857059
}
Packit 857059
Packit 857059
#if defined(VXWORKS)
Packit 857059
void
Packit 857059
MemoryAllocateVxWorksTrack(
Packit 857059
	IN void *result,
Packit 857059
	IN uint32 Bytes,
Packit 857059
	IN char *reason,
Packit 857059
	IN void *caller) 
Packit 857059
{
Packit 857059
	MemoryTrackerTrackAllocation(reason, (int)caller, Bytes, IBA_MEM_FLAG_NONE, result, NULL);
Packit 857059
}
Packit 857059
#endif
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocate2Dbg(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine, 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags,
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	void			*pMem;
Packit 857059
Packit 857059
#ifdef MEM_TRACK_FTR
Packit 857059
	// Increase the size of our allocation to account for the footer.
Packit 857059
	Bytes += sizeof( MEM_ALLOC_FTR );
Packit 857059
	Bytes = (Bytes + 3) >> 2 << 2;
Packit 857059
#endif  // MEM_TRACK_FTR
Packit 857059
Packit 857059
	// Allocate the memory first, so that we give the user's allocation 
Packit 857059
	// priority over the the header allocation.
Packit 857059
	pMem = MEMORY_ALLOCATE_PRIV( Bytes, flags, Tag );
Packit 857059
Packit 857059
	if( !pMem )
Packit 857059
		return NULL;
Packit 857059
Packit 857059
	MemoryTrackerTrackAllocation(pFileName, nLine, Bytes, flags, pMem,
Packit 857059
#ifdef MEM_TRACK_FTR
Packit 857059
			(MEM_ALLOC_FTR*)((uchar*)pMem + Bytes - sizeof( MEM_ALLOC_FTR ))
Packit 857059
#else
Packit 857059
			NULL
Packit 857059
#endif
Packit 857059
			);
Packit 857059
Packit 857059
	return pMem;
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocateRel(
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocateDbg( "Unknown", 0, Bytes, IsPageable, Tag );
Packit 857059
}
Packit 857059
void*
Packit 857059
MemoryAllocate2Rel(
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags,
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocate2Dbg( "Unknown", 0, Bytes, flags, Tag );
Packit 857059
}
Packit 857059
Packit 857059
#if defined(VXWORKS)
Packit 857059
void*
Packit 857059
MemoryAllocatePhysContDbg(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine, 
Packit 857059
	IN uint32 Bytes )
Packit 857059
{
Packit 857059
	void			*pMem;
Packit 857059
Packit 857059
	/* no footer on PhysCont allocates, they tend to be a full page
Packit 857059
	 * and a footer would waste another page, TBD we could round up
Packit 857059
	 * provided resulting Bytes was still same number of pages
Packit 857059
	 */
Packit 857059
Packit 857059
	// Allocate the memory first, so that we give the user's allocation 
Packit 857059
	// priority over the the header allocation.
Packit 857059
	pMem = MEMORY_ALLOCATE_PHYS_CONT_PRIV( Bytes );
Packit 857059
Packit 857059
	if( !pMem )
Packit 857059
		return NULL;
Packit 857059
Packit 857059
	MemoryTrackerTrackAllocation(pFileName, nLine, Bytes, IBA_MEM_FLAG_PREMPTABLE, pMem, NULL);
Packit 857059
Packit 857059
	return pMem;
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocatePhysContRel(
Packit 857059
	IN uint32 Bytes )
Packit 857059
{
Packit 857059
	return MemoryAllocatePhysContDbg( "Unknown", 0, Bytes );
Packit 857059
}
Packit 857059
#endif /* defined(VXWORKS) */
Packit 857059
#else	// !MEM_TRACK_ON
Packit 857059
void*
Packit 857059
MemoryAllocateDbg(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine, 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MEMORY_ALLOCATE_PRIV( Bytes,
Packit 857059
					(IsPageable?IBA_MEM_FLAG_PAGEABLE:IBA_MEM_FLAG_NONE)
Packit 857059
					|IBA_MEM_FLAG_LEGACY, Tag );
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocate2Dbg(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine, 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags,
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MEMORY_ALLOCATE_PRIV( Bytes, flags, Tag);
Packit 857059
}
Packit 857059
void*
Packit 857059
MemoryAllocateRel(
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MEMORY_ALLOCATE_PRIV( Bytes, 
Packit 857059
					(IsPageable?IBA_MEM_FLAG_PAGEABLE:IBA_MEM_FLAG_NONE)
Packit 857059
					|IBA_MEM_FLAG_LEGACY, Tag );
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocate2Rel(
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags,
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MEMORY_ALLOCATE_PRIV( Bytes, flags, Tag);
Packit 857059
}
Packit 857059
Packit 857059
#if defined(VXWORKS)
Packit 857059
void*
Packit 857059
MemoryAllocatePhysContDbg(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine, 
Packit 857059
	IN uint32 Bytes )
Packit 857059
{
Packit 857059
	return MEMORY_ALLOCATE_PHYS_CONT_PRIV( Bytes );
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocatePhysContRel(
Packit 857059
	IN uint32 Bytes )
Packit 857059
{
Packit 857059
	return MEMORY_ALLOCATE_PHYS_CONT_PRIV( Bytes );
Packit 857059
}
Packit 857059
#endif /* defined(VXWORKS) */
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
Packit 857059
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
void*
Packit 857059
MemoryAllocateAndClearDbg( 
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine,
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocate2AndClearDbg(pFileName, nLine, Bytes,
Packit 857059
					(IsPageable?IBA_MEM_FLAG_PAGEABLE:IBA_MEM_FLAG_NONE)
Packit 857059
					|IBA_MEM_FLAG_LEGACY, Tag );
Packit 857059
}
Packit 857059
void*
Packit 857059
MemoryAllocate2AndClearDbg( 
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine,
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags,
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	void	*pBuffer;
Packit 857059
Packit 857059
	if( (pBuffer = MemoryAllocate2Dbg( pFileName, nLine, Bytes, flags, Tag )) != NULL )
Packit 857059
	{
Packit 857059
		MemoryClear( pBuffer, Bytes );
Packit 857059
	}
Packit 857059
Packit 857059
	return pBuffer;
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocateAndClearRel( 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocateAndClearDbg("Unknown", 0, Bytes, IsPageable, Tag);
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocate2AndClearRel( 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags,
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocate2AndClearDbg("Unknown", 0, Bytes, flags, Tag);
Packit 857059
}
Packit 857059
Packit 857059
#else	// !MEM_TRACK_ON
Packit 857059
void*
Packit 857059
MemoryAllocateAndClearDbg( 
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine,
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocate2AndClear(Bytes,
Packit 857059
					(IsPageable?IBA_MEM_FLAG_PAGEABLE:IBA_MEM_FLAG_NONE)
Packit 857059
					|IBA_MEM_FLAG_LEGACY, Tag );
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocate2AndClearDbg( 
Packit 857059
	IN const char *pFileName, 
Packit 857059
	IN int32 nLine,
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocate2AndClear(Bytes, flags, Tag);
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocateAndClearRel( 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	return MemoryAllocate2AndClear(Bytes,
Packit 857059
					(IsPageable?IBA_MEM_FLAG_PAGEABLE:IBA_MEM_FLAG_NONE)
Packit 857059
					|IBA_MEM_FLAG_LEGACY, Tag );
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocate2AndClearRel( 
Packit 857059
	IN uint32 Bytes, 
Packit 857059
	IN uint32 flags,
Packit 857059
	IN uint32 Tag )
Packit 857059
{
Packit 857059
	void	*pBuffer;
Packit 857059
Packit 857059
	if( (pBuffer = MEMORY_ALLOCATE_PRIV( Bytes, flags, Tag )) != NULL )
Packit 857059
	{
Packit 857059
		MemoryClear( pBuffer, Bytes );
Packit 857059
	}
Packit 857059
Packit 857059
	return pBuffer;
Packit 857059
}
Packit 857059
#endif	// !MEM_TRACK_ON
Packit 857059
Packit 857059
Packit 857059
int
Packit 857059
MemoryDeallocate( 
Packit 857059
	IN void *pMemory )
Packit 857059
{
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
	int result;
Packit 857059
Packit 857059
	if (pMemory == NULL)
Packit 857059
		return 0;
Packit 857059
Packit 857059
	result = MemoryTrackerTrackDeallocate(pMemory );
Packit 857059
	MEMORY_DEALLOCATE_PRIV( pMemory );
Packit 857059
	return result;
Packit 857059
#else
Packit 857059
	MEMORY_DEALLOCATE_PRIV( pMemory );
Packit 857059
	return 0;
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
Packit 857059
}
Packit 857059
Packit 857059
#if defined(VXWORKS)
Packit 857059
void
Packit 857059
MemoryDeallocatePhysCont( 
Packit 857059
	IN void *pMemory )
Packit 857059
{
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
	(void)MemoryTrackerTrackDeallocate(pMemory );
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
	MEMORY_DEALLOCATE_PHYS_CONT_PRIV( pMemory );
Packit 857059
}
Packit 857059
#endif /* defined(VXWORKS) */
Packit 857059
Packit 857059
void
Packit 857059
MemoryClear( 
Packit 857059
	IN void *pMemory, 
Packit 857059
	IN uint32 Bytes )
Packit 857059
{
Packit 857059
	MemoryFill( pMemory, 0, Bytes );
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
void*
Packit 857059
MemoryAllocateObjectArrayRel(
Packit 857059
	IN uint32 ObjectCount, 
Packit 857059
	IN OUT uint32 *pObjectSize,  
Packit 857059
	IN uint32 ByteAlignment, 
Packit 857059
	IN uint32 AlignmentOffset,
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag,
Packit 857059
	OUT void **ppFirstObject, 
Packit 857059
	OUT uint32 *pArraySize )
Packit 857059
{
Packit 857059
	return MemoryAllocateObjectArrayDbg("Unknown", 0, ObjectCount, pObjectSize,
Packit 857059
						ByteAlignment, AlignmentOffset, IsPageable, Tag,
Packit 857059
						ppFirstObject, pArraySize);
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocateObjectArrayDbg(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	int32 nLine,
Packit 857059
	IN uint32 ObjectCount, 
Packit 857059
	IN OUT uint32 *pObjectSize,  
Packit 857059
	IN uint32 ByteAlignment, 
Packit 857059
	IN uint32 AlignmentOffset,
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag,
Packit 857059
	OUT void **ppFirstObject, 
Packit 857059
	OUT uint32 *pArraySize )
Packit 857059
#else	// !MEM_TRACK_ON
Packit 857059
void*
Packit 857059
MemoryAllocateObjectArrayDbg(
Packit 857059
	IN const char *pFileName, 
Packit 857059
	int32 nLine,
Packit 857059
	IN uint32 ObjectCount, 
Packit 857059
	IN OUT uint32 *pObjectSize,  
Packit 857059
	IN uint32 ByteAlignment, 
Packit 857059
	IN uint32 AlignmentOffset,
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag,
Packit 857059
	OUT void **ppFirstObject, 
Packit 857059
	OUT uint32 *pArraySize )
Packit 857059
{
Packit 857059
	return MemoryAllocateObjectArrayRel(ObjectCount, pObjectSize, ByteAlignment,
Packit 857059
						AlignmentOffset, IsPageable, Tag,
Packit 857059
						ppFirstObject, pArraySize);
Packit 857059
}
Packit 857059
Packit 857059
void*
Packit 857059
MemoryAllocateObjectArrayRel(
Packit 857059
	IN uint32 ObjectCount, 
Packit 857059
	IN OUT uint32 *pObjectSize,  
Packit 857059
	IN uint32 ByteAlignment, 
Packit 857059
	IN uint32 AlignmentOffset,
Packit 857059
	IN boolean IsPageable, 
Packit 857059
	IN uint32 Tag,
Packit 857059
	OUT void **ppFirstObject, 
Packit 857059
	OUT uint32 *pArraySize )
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
{
Packit 857059
	void	*pArray;
Packit 857059
Packit 857059
	ASSERT( ObjectCount && *pObjectSize && AlignmentOffset < *pObjectSize );
Packit 857059
Packit 857059
	if( ByteAlignment > 1)
Packit 857059
	{
Packit 857059
		// Fixup the object size based on the alignment specified.
Packit 857059
		*pObjectSize = ((*pObjectSize) + ByteAlignment - 1) -
Packit 857059
			(((*pObjectSize) + ByteAlignment - 1) % ByteAlignment);
Packit 857059
	}
Packit 857059
Packit 857059
	// Determine the size of the buffer to allocate.
Packit 857059
	*pArraySize = (ObjectCount * (*pObjectSize)) + ByteAlignment;
Packit 857059
Packit 857059
	// Allocate the array of objects.
Packit 857059
#if defined(MEM_TRACK_ON)
Packit 857059
	if( !(pArray = MemoryAllocateAndClearDbg( pFileName, nLine, *pArraySize, 
Packit 857059
		IsPageable, Tag )) )
Packit 857059
#else	// !MEM_TRACK_ON
Packit 857059
	if( !(pArray = MemoryAllocateAndClear( *pArraySize, IsPageable, Tag )) )
Packit 857059
Packit 857059
#endif	// MEM_TRACK_ON
Packit 857059
	{
Packit 857059
		*pArraySize = 0;
Packit 857059
		return NULL;
Packit 857059
	}
Packit 857059
Packit 857059
	if( ByteAlignment > 1 )
Packit 857059
	{
Packit 857059
		// Calculate the pointer to the first object that is properly aligned.
Packit 857059
		*ppFirstObject = (void*)(
Packit 857059
			((uchar*)pArray + AlignmentOffset + ByteAlignment - 1) - 
Packit 857059
			(((uintn)pArray + AlignmentOffset + ByteAlignment - 1) %
Packit 857059
			ByteAlignment ));
Packit 857059
	}
Packit 857059
	else
Packit 857059
	{
Packit 857059
		*ppFirstObject = pArray;
Packit 857059
	}
Packit 857059
	return pArray;
Packit 857059
}
Packit 857059