home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware 1 2 the Maxx
/
sw_1.zip
/
sw_1
/
WINDOWS
/
MISC
/
XLMATH10.ZIP
/
XLMUTIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-14
|
8KB
|
323 lines
/*******************************************************************
XLMUTIL.C
==========
Author: Roy Kari
Dept. of Chemistry
Laurentian University
Sudbury, Ont.
Canada P3E 2C6
(705) 675-1151
Internet: "ROY@NICKEL.LAURENTIAN.CA"
This module contains all of the memory management routines for
the XLMATH module. The memory management is done with the aid
of the OPTIMEM memory manager (c) Applegate Software (206)868-8512.
The author strongly recommends the purchase of this memory manager
as a means of avoiding untold frustrations in both the comprehension
and use of Windows 3 memory management.
***************************************************************** */
/* --------------------------< Include files >--------------------- */
#include <windows.h>
#include <stdlib.h>
#include "xlmopti.h"
#include "xlmath.h"
#include "xlmutil.h"
extern OMEM_POOL ReturnPool;
extern OMEM_POOL ScratchPool;
extern HANDLE hLibInst;
extern char *szLibName;
extern TD TaskDescriptors[];
/*** Global Variables ***/
static char szErrorBuf[MAX_ERROR_STRING];
// function prototypes
static NPTD PASCAL FindTaskDescriptor(HANDLE hTask);
/********************************************************************
ExpungeTaskDescriptor()
=======================
This function deletes a task descriptor and any memory associated
with the descriptor block.
********************************************************************/
BOOL PASCAL ExpungeTaskDescriptor(HANDLE hTask)
{
NPTD pTaskDesc = FindTaskDescriptor(hTask);
HANDLE hGlobal;
if (!pTaskDesc)
return FALSE;
if (pTaskDesc->lpReturnBuffer)
MemFreePtr(pTaskDesc->lpReturnBuffer);
pTaskDesc->lpReturnBuffer = NULL;
pTaskDesc->hTask = NULL;
return TRUE;
}
/********************************************************************
FindTaskDescriptor()
====================
This function gets a pointer to the currently active tasks
descriptor block or returns NULL if none found. When called
with hTask = NULL, finds first available slot for new block.
********************************************************************/
static NPTD PASCAL FindTaskDescriptor(HANDLE hTask)
{
WORD wCount = MAX_TASK_DESC;
NPTD pTaskDesc = &TaskDescriptors[0];
while (wCount--)
if (pTaskDesc->hTask == hTask)
return pTaskDesc;
else
++pTaskDesc;
return NULL;
}
/********************************************************************
GetTaskDescriptor()
================
This function gets a pointer to the currently active task's
descriptor block. If not found then creates a new one
********************************************************************/
NPTD PASCAL GetTaskDescriptor(HANDLE hTask)
{
NPTD pTaskDesc = FindTaskDescriptor(hTask);
if (pTaskDesc)
return pTaskDesc;
// a new task
pTaskDesc = FindTaskDescriptor(0); // look for empty one
if (pTaskDesc)
{
pTaskDesc->hTask = hTask;
pTaskDesc->lpReturnBuffer = NULL;
return pTaskDesc;
}
else
{
ErrorHandler(XLM_NO_TASK);
return NULL;
}
}
/********************************************************************
InitRetBuff()
=============
This function allocates the XL transfer array in global memory &
inits the array. If hXLInt is NULL it will allocate, otherwise
reallocate.
********************************************************************/
LPFP PASCAL InitRetBuff(WORD wRows, WORD wCols)
{
WORD wBlockSize = sizeof(WORD)*2 + sizeof(double)*wRows*wCols;
WORD i;
LPFP lpXLInt = NULL;
NPTD pTaskDesc;
pTaskDesc = GetTaskDescriptor(GetCurrentTask());
if (pTaskDesc != NULL)
{
if ((lpXLInt = pTaskDesc->lpReturnBuffer) != NULL)
{
// previously used memory is reallocated
lpXLInt = (LPFP)MemReAllocPtr((LPVOID) lpXLInt,
wBlockSize, TRUE);
}
else
{
lpXLInt = (LPFP)MemAllocPtr(ReturnPool,
wBlockSize, TRUE);
}
// init array
if (lpXLInt != NULL)
{
pTaskDesc->lpReturnBuffer = lpXLInt;
lpXLInt->wRows = wRows;
lpXLInt->wCols = wCols;
for (i = 0; i < wRows*wCols; i++)
lpXLInt->Data[i] = 0.0;
}
}
else
ErrorHandler(XLM_NULL_TASK);
return (lpXLInt);
}
/********************************************************************
GetMem()
=============
This function allocates memory for temporary storage
********************************************************************/
LPVOID PASCAL GetMem(WORD wBytes)
{
LPVOID lpPtr = (LPVOID)MemAllocPtr(ScratchPool, wBytes, FALSE);
if (lpPtr == NULL)
ErrorHandler(XLM_NO_MEMORY);
return (lpPtr);
}
/********************************************************************
FreeMem()
=============
This function de-allocates memory previously allocated in GetMem()
********************************************************************/
void PASCAL FreeMem(LPVOID lpPtr)
{
if ((MemFreePtr((LPVOID)lpPtr) == FALSE))
ErrorHandler(XLM_MEMORY_ERROR);
lpPtr = NULL;
}
/********************************************************************
InitPointers()
=============
This function allocates memory and calculates the pointers for a 2-D
array. Note: prior to setting pointers, the array data must be Locked
in memory so that the pointers remain valid
********************************************************************/
LPLPREAL PASCAL InitPointers(LPREAL lpData,
WORD wRows, WORD wCols)
{
WORD id;
LPLPREAL lplpPtrs;
WORD wBytes = sizeof(LPREAL)*wRows;
if ((lplpPtrs= (LPLPREAL)GetMem(wBytes)) == NULL)
{
ErrorHandler(XLM_NO_MEMORY);
return NULL;
}
// init row pointers
for(id = 0; id < wRows; id++)
{
lplpPtrs[id] = lpData;
lpData += wCols;
}
return(lplpPtrs);
}
/********************************************************************
CleanMemory()
=============
This function is called when a task terminates
********************************************************************/
void PASCAL CleanMemory(void)
{
WORD wCount = MAX_TASK_DESC;
NPTD pTaskDesc = &TaskDescriptors[0];
WORD wActiveTasks = 0;
DWORD dwCountScratch = MemPoolCount(ScratchPool);
DWORD dwCountReturn = MemPoolCount(ReturnPool);
// count no. active tasks
while (wCount--)
{
if (pTaskDesc->hTask)
++wActiveTasks;
++pTaskDesc;
}
// never have ScratchPool blocks
if (dwCountScratch > 0)
ErrorHandler(XLM_SMEM_ERROR);
// only one per active task
if (dwCountReturn > wActiveTasks)
ErrorHandler(XLM_RMEM_ERROR);
}
/********************************************************************
ErrorHandler()
================
This function is used to display an error message
********************************************************************/
BOOL PASCAL ErrorHandler(XLM_ERROR nErrorCode)
{
int nResult;
MessageBeep(0);
if (LoadString(hLibInst, nErrorCode, szErrorBuf, MAX_ERROR_STRING) > 0)
{
if ((nResult = MessageBox(0, szErrorBuf, szLibName,
MB_OK | MB_ICONHAND | MB_TASKMODAL)) == 0)
nResult = MessageBox(0, szErrorBuf, szLibName,
MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
return nResult == IDRETRY;
}
else
return FALSE;
}
#ifdef SUB_OPTIMEM
OMEM_POOL PASCAL MemPoolInit(BOOL bShared)
{
return (OMEM_POOL)NULL;
}
BOOL PASCAL MemPoolFree(OMEM_POOL pool)
{
return TRUE;
}
DWORD PASCAL MemPoolCount(OMEM_POOL pool)
{
return (DWORD)0;
}
LPVOID PASCAL MemAllocPtr(OMEM_POOL pool, WORD wSize,
BOOL bZeroInit)
{
HANDLE hGlobal;
LPVOID lpPtr;
WORD wFlags = GMEM_MOVEABLE;
if (bZeroInit)
wFlags = wFlags | GMEM_ZEROINIT;
if ((hGlobal = GlobalAlloc(wFlags, (DWORD)wSize)) == NULL)
return (LPVOID)NULL;
else
return (LPVOID)GlobalLock(hGlobal);
}
LPVOID PASCAL MemReAllocPtr(LPVOID lpMem, WORD wSize,
BOOL bZeroInit)
{
HANDLE hGlobal = LOWORD(GlobalHandle(HIWORD(lpMem)));
LPVOID lpPtr;
WORD wFlags = GMEM_MOVEABLE;
if (bZeroInit)
wFlags = wFlags | GMEM_ZEROINIT;
GlobalUnlock(hGlobal);
if ((hGlobal = GlobalReAlloc(hGlobal,(DWORD)wSize, wFlags))
== NULL)
return (LPVOID)NULL;
else
return (LPVOID)GlobalLock(hGlobal);
}
BOOL PASCAL MemFreePtr(LPVOID lpPtr)
{
HANDLE hGlobal = LOWORD(GlobalHandle(HIWORD(lpPtr)));
GlobalUnlock(hGlobal);
GlobalFree(hGlobal);
return TRUE;
}
#endif