|
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 |
|