📄 cmmnrsrc.c
字号:
/*
* Copyright (C) Ericsson Mobile Communications AB, 2000.
* Licensed to AU-System AB.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and AU-System AB, and may be used and copied
* only in accordance with the terms of the said agreement.
*
* Neither Ericsson Mobile Communications AB nor AU-System AB
* assumes any responsibility or liability for any errors or inaccuracies in
* this software, or any consequential, incidental or indirect damage arising
* out of the use of the Generic WAP Client software.
*/
#include "wiptrgt.h"
#include "cmmnrsrc.h"
#include "waectype.h"
#include "aapiclnt.h"
#include "wipprdct.h"
#include "wipvrsn.h"
#ifdef USE_WIP_MALLOC
#include "wip_mem.h"
#endif
#ifndef CBASIC_WITH_NO_CONNECTORS
#include "wiptimer.h"
#include "ml_typw.h"
#include "wap.ifc"
#endif
#if defined LOG_INTERNAL
#include <stdio.h>
extern int logCount;
#endif
#if defined NO_GLOBAL_VARS
#include "userdata.h"
#endif
/**********************************************************
ABOUT THIS SYSTEM
**********************************************************/
#ifndef WIP_PRODUCT
#error WIP_PRODUCT not defined
#endif
#ifndef WIP_VERSION
#error WIP_VERSION not defined
#endif
#ifndef WAP_SERIAL
#define WAP_SERIAL "00000000"
#endif
#define ABOUT__PRODUCT_VERSION WIP_PRODUCT ## "-" ## WIP_VERSION
#define ABOUT__SERIAL "Serial No: " ## WAP_SERIAL
const char * const aboutStrings[3] =
{
ABOUT__PRODUCT_VERSION,
ABOUT__SERIAL,
NULL
};
/**********************************************************
SECTION FOR HEADER MANAGEMENT FOR MEMORY ALLOCATOR
**********************************************************/
#if !defined USE_WIP_MALLOC
typedef struct meminfo
{
void *prev;
void *next;
#if defined USE_MEMORY_GUARD || defined MEMORY_METER
UINT32 size;
#endif
#ifdef LOG_INTERNAL
long line;
long id;
char file[FILENAME_MAX];
#endif
} meminfo;
#define PREV(memory) (((meminfo *)memory)->prev)
#define NEXT(memory) (((meminfo *)memory)->next)
/* round up to nearest multiple of MEM_ADDRESS_ALIGNMENT */
#define ROUND2(n) \
( ( n + MEM_ADDRESS_ALIGNMENT - 1) & ~(MEM_ADDRESS_ALIGNMENT - 1) )
#define SIZE_OF_HEAD ROUND2(sizeof(meminfo))
#define NO_OF_VOIDSTAR (SIZE_OF_HEAD / sizeof(void*))
#endif
#ifdef USE_WIP_MALLOC
#define SIZE_OF_OVERHEAD 0
#else
#if defined USE_MEMORY_GUARD || defined MEMORY_METER
#define SIZE_OF_OVERHEAD 12
#else
#define SIZE_OF_OVERHEAD 8
#endif
#endif
/**********************************************************
CODE FOR MEMORY ALLOCATOR
**********************************************************/
static UINT8 handleException(void);
#ifdef MEMORY_METER
static void memoryMeterAdjust(VOID *memory, UINT32 size);
static void memoryMeterReset(void);
#endif
#ifdef USE_MEMORY_GUARD
static BOOL memoryGuardCheck(UINT32 size);
static void memoryGuardAdjust(VOID *memory, UINT32 size);
static void memoryGuardReset(void);
#endif
#ifdef LOG_INTERNAL
static void memoryLogNew(VOID *memory, UINT32 size, const char *file, int line);
static void memoryLogDelete(VOID *memory, const char *file, int line);
static void memoryLogPrint(VOID *list);
#endif
#ifndef USE_WIP_MALLOC
static void memoryListNew(VOID *memory);
static void memoryListDelete(VOID *memory);
static void memoryListDeleteAll(void);
#ifdef LOG_INTERNAL
static void memoryListPrint(void);
#endif
#endif
#ifndef HAS_SETJMP
extern BOOL exception;
#endif
#define RETURN 1
#define RETRY 2
#ifdef LOG_INTERNAL
VOID* WIPAlloc(UINT32 size, const char *file, int line)
#else
VOID* WIPAlloc(UINT32 size)
#endif
{
VOID *memory = NULL;
#ifdef USE_MEMORY_GUARD
if (memoryGuardCheck(size))
{
/* handleException does not return if the macro
HAS_SETJMP is set, and the memory
allocation is done from SDL when it is
unsafe to return NULL. */
UINT8 res = handleException();
if (res == RETURN)
return NULL;
/* else res == RETRY */
}
#endif
#ifndef HAS_SETJMP
retry:
#endif
#ifdef USE_WIP_MALLOC
memory = wip_gcmalloc(size);
#else
memory = malloc(size + SIZE_OF_HEAD);
#endif
if (memory == NULL)
{
/* handleException does not return if the macro
HAS_SETJMP is set, and the memory
allocation is done from SDL when it is
unsafe to return NULL. */
UINT8 res = handleException();
if (res == RETURN)
return NULL;
#ifndef HAS_SETJMP
else /* res == RETRY */
goto retry;
#endif
}
if (memory)
{
#ifdef MEMORY_METER
memoryMeterAdjust(memory, size + SIZE_OF_OVERHEAD);
#endif
#ifdef USE_MEMORY_GUARD
memoryGuardAdjust(memory, size + SIZE_OF_OVERHEAD);
#endif
#if defined LOG_INTERNAL
memoryLogNew(memory, size + SIZE_OF_OVERHEAD, file, line);
#endif
#if !defined USE_WIP_MALLOC
memoryListNew(memory);
#endif
#if !defined USE_WIP_MALLOC
memory = (void **)memory + NO_OF_VOIDSTAR;
#endif
}
return memory;
}
#ifdef LOG_INTERNAL
VOID WIPFree( VOID* memory, const char *file, int line )
#else
VOID WIPFree( VOID* memory )
#endif
{
void *t;
if (!memory)
return;
#if !defined USE_WIP_MALLOC
t = (void **)memory - NO_OF_VOIDSTAR;
#else
t = (void **)memory;
#endif
#ifdef MEMORY_METER
memoryMeterAdjust(t, 0);
#endif
#ifdef USE_MEMORY_GUARD
memoryGuardAdjust(t, 0);
#endif
#if defined LOG_INTERNAL
memoryLogDelete(t, file, line);
#endif
#if !defined USE_WIP_MALLOC
memoryListDelete(t);
#endif
#ifdef USE_WIP_MALLOC
wip_free(t);
#else
free(t);
#endif
}
void deleteAllMemory(void)
{
#ifdef USE_MEMORY_GUARD
memoryGuardReset();
#endif
#ifdef MEMORY_METER
memoryMeterReset();
#endif
#if !defined USE_WIP_MALLOC
#if defined LOG_INTERNAL
memoryListPrint();
#endif
memoryListDeleteAll();
#else
#if defined LOG_INTERNAL
memoryLogPrint (0);
#endif
wip_gc();
#endif
}
/**********************************************************
EXCEPTION HANDLER USED BY MEMORY ALLOCATOR
**********************************************************/
#ifndef NO_GLOBAL_VARS
#ifdef HAS_SETJMP
#ifdef XSCT_CMICRO
extern jmp_buf jmpbuf;
#endif
#else
extern char *safetyblock;
#endif
BOOL unsafeToReturnNull = TRUE;
BOOL executingSDL = FALSE;
#endif
static UINT8 handleException(void)
{
#ifdef XSCT_CMICRO
if (executingSDL && unsafeToReturnNull)
{
#ifdef HAS_SETJMP
CLNTa_error(0, ERR_OUT_OF_MEMORY, ERRTYPE_FATAL);
longjmp(jmpbuf, 1); /* exception! long jump to CLNTc_start */
#else
if (!exception)
{
exception = TRUE;
OSConnectorFree(safetyblock);
CLNTa_error(0, ERR_OUT_OF_MEMORY, ERRTYPE_FATAL);
return RETRY;
}
#endif
}
else if (!executingSDL) /* in connector function */
{
deleteAllTimers();
deleteAllMemory();
CLNTa_error(0, ERR_OUT_OF_MEMORY, ERRTYPE_FATAL);
}
#endif
return RETURN;
}
/* TRUE means that the memory allocator never returns
if out of memory occurs (if HAS_SETJMP). If !HAS_SETJMP
the MBM buffers are freed. The memory allocator tries
then to allocate one more time and returns after that.
If we are lucky the functions return safaly to CLNT_run
were the exception is trigered.
FALSE means that the memory allocator returns NULL
if out of memory occurs.
The function returns the old value. */
BOOL SetMemoryGuard(BOOL trueOrFalse)
{
BOOL oldValue = unsafeToReturnNull;
unsafeToReturnNull = trueOrFalse;
return oldValue;
}
/**********************************************************
MEMORY METER USED BY TEST BROWSER
**********************************************************/
#ifdef MEMORY_METER
static long memoryMeter = 0;
long currentMemoryMeterMax = 0;
static void memoryMeterAdjust(VOID *memory, UINT32 size)
{
if (size != 0) /* new memory */
{
#ifdef USE_WIP_MALLOC
memoryMeter += wip_memsize (memory);
#else
#ifndef USE_MEMORY_GUARD
meminfo *t = (meminfo *) memory;
t->size = size;
#endif
memoryMeter += size;
/*
currentMemoryMeterMax is reset to zero
every time the test browser reads it
*/
if (currentMemoryMeterMax < memoryMeter)
currentMemoryMeterMax = memoryMeter;
#endif
}
else /* delete memory */
{
#ifdef USE_WIP_MALLOC
memoryMeter -= wip_memsize (memory);
#else
meminfo *t = (meminfo *) memory;
memoryMeter -= t->size;
#endif
}
}
static void memoryMeterReset(void)
{
memoryMeter = 0;
currentMemoryMeterMax = 0;
}
#endif
/**********************************************************
MEMORY COUNTER USED BY MEMORY ALLOCATOR
**********************************************************/
#ifdef USE_MEMORY_GUARD
static long memcount = 0;
static BOOL memoryGuardCheck(UINT32 size)
{
BOOL overTheLimit = (memcount + size) > MEMORY_LIMIT;
if (overTheLimit)
return TRUE;
else
return FALSE;
}
static void memoryGuardAdjust(VOID *memory, UINT32 size)
{
#ifndef CBASIC_WITH_NO_CONNECTORS
XMK_SEND_TMP_VARS
#endif
#ifdef USE_WIP_MALLOC
if (size != 0) /* new memory */
{
BOOL alreadyWarned = memcount > MEMORY_WARNING;
BOOL warning;
memcount += wip_memsize (memory);
warning = memcount > MEMORY_WARNING;
#ifndef CBASIC_WITH_NO_CONNECTORS
if (warning && !alreadyWarned)
{
XMK_SEND_ENV( ENV,
DiscardAllContext,
xDefaultPrioSignal,
0,
NULL,
GLOBALPID(XPTID_UA_ME,0));
CLNTa_error(0, ERR_MEMORY_WARNING, ERRTYPE_CRITICAL);
}
#endif
}
else /* delete memory */
{
memcount -= wip_memsize (memory);
}
#else
meminfo *t = (meminfo *) memory;
if (size != 0) /* new memory */
{
BOOL alreadyWarned = memcount > MEMORY_WARNING;
BOOL warning;
t->size = size;
memcount += size;
warning = memcount > MEMORY_WARNING;
#ifndef CBASIC_WITH_NO_CONNECTORS
if (warning && !alreadyWarned)
{
XMK_SEND_ENV( ENV,
DiscardAllContext,
xDefaultPrioSignal,
0,
NULL,
GLOBALPID(XPTID_UA_ME,0));
CLNTa_error(0, ERR_MEMORY_WARNING, ERRTYPE_CRITICAL);
}
#endif
}
else /* delete memory */
{
memcount -= t->size;
}
#endif
}
static void memoryGuardReset(void)
{
memcount = 0;
}
#endif
/**********************************************************
LOG FACILITY USED BY MEMORY ALLOCATOR
**********************************************************/
#ifdef LOG_INTERNAL
static int memid = 0;
static FILE *OpenMemFile(void)
{
static FILE *s_pMEMFILE = NULL;
if (!s_pMEMFILE)
s_pMEMFILE = fopen("WAP.mem", "wb");
else
s_pMEMFILE = fopen("WAP.mem", "a+b");
return s_pMEMFILE;
}
static void memoryLogNew(VOID *memory, UINT32 size, const char *file, int line)
{
FILE *pFILE = OpenMemFile();
#ifdef USE_WIP_MALLOC
size = wip_memsize (memory);
fprintf (pFILE, "%d\t+%d = %d\tLogNo: %d\t%s[%d]\n", memid, size, memcount, logCount, file, line);
#else
meminfo *t = (meminfo *) memory;
size_t fileLen = strlen(file);
strncpy(t->file, file, fileLen);
t->file[fileLen] = 0;
t->line = line;
t->id = memid;
fprintf(pFILE, "%d\t+%d = %d\tLogNo: %d\t%s[%d]\n", memid, size, memcount, logCount, file, line);
#endif
fclose(pFILE);
memid++;
}
static void memoryLogDelete(VOID *memory, const char *file, int line)
{
FILE *pFILE = OpenMemFile();
#ifdef USE_WIP_MALLOC
fprintf (pFILE, "%d\t-%d = %d\tLogNo: %d\t%s[%d]\n", 0,
wip_memsize (memory), memcount, logCount, file, line);
#else
meminfo *t = (meminfo *)memory;
fprintf(pFILE, "%d\t-%d = %d\tLogNo: %d\t%s[%d]\n", t->id, t->size, memcount, logCount, file, line);
#endif
fclose(pFILE);
}
static void memoryLogPrint(VOID *list)
{
const char cszStart[] = "\n************ START EJ AVALLOKERAT MINNE *************\n";
const char cszEnd[] = "************ SLUT EJ AVALLOKERAT MINNE *************\n\n";
FILE *pFILE = OpenMemFile();
#ifdef USE_WIP_MALLOC
fprintf(pFILE, cszStart);
wip_printalloc(pFILE);
#else
void *i = list;
fprintf(pFILE, cszStart);
while (i != NULL)
{
void *t0 = i;
meminfo *t = (meminfo *)t0;
fprintf(pFILE, "id: %d\tsize: %d\t%s[%d]\n", t->id, t->size, t->file, t->line);
i = NEXT(i);
}
#endif
fprintf(pFILE, cszEnd);
fclose(pFILE);
}
#endif
/**********************************************************
MEMORY BLOCK LIST USED BY MEMORY ALLOCATOR
**********************************************************/
#if !defined USE_WIP_MALLOC
#ifndef NO_GLOBAL_VARS
void *memblocks = NULL;
#endif
static void memoryListNew(VOID *memory)
{
PREV(memory) = NULL;
if (memblocks)
{
PREV(memblocks) = memory;
NEXT(memory) = memblocks;
}
else
{
NEXT(memory) = NULL;
}
memblocks = memory;
}
static void memoryListDelete(VOID *memory)
{
if (PREV(memory) && NEXT(memory))
{
NEXT(PREV(memory)) = NEXT(memory);
PREV(NEXT(memory)) = PREV(memory);
}
else if (PREV(memory))
{
NEXT(PREV(memory)) = NULL;
}
else if (NEXT(memory))
{
PREV(NEXT(memory)) = NULL;
memblocks = NEXT(memory);
}
else
{
memblocks = NULL;
}
}
static void memoryListDeleteAll(void)
{
void *i = memblocks;
while (i != NULL)
{
void *t0 = i;
i = NEXT(i);
free(t0);
}
memblocks = NULL;
}
#if defined LOG_INTERNAL
static void memoryListPrint(void)
{
memoryLogPrint(memblocks);
}
#endif
#endif
/**********************************************************
CODE FOR LOG FUNCTIONALITY
**********************************************************/
#if defined LOG_EXTERNAL
static void char2hex(char ch, char *str)
{
unsigned char h_nibble = (ch >> 4) & 0x0F;
unsigned char l_nibble = ch & 0x0F;
if (h_nibble < 10)
str[0] = 48 + h_nibble;
else
str[0] = 55 + h_nibble;
if (l_nibble < 10)
str[1] = 48 + l_nibble;
else
str[1] = 55 + l_nibble;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -