git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@1009 0109f412-320b-0410-ab79-c3e0c5ffbbe6
1426 lines
32 KiB
C++
1426 lines
32 KiB
C++
//-------------------------------------------------------------------------
|
|
// Desc: Gigatest
|
|
// Tabs: 3
|
|
//
|
|
// Copyright (c) 2000-2007 Novell, Inc. All Rights Reserved.
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; version 2.1
|
|
// of the License.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Library Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, contact Novell, Inc.
|
|
//
|
|
// To contact Novell about this file by physical or electronic mail,
|
|
// you may find current contact information at www.novell.com.
|
|
//
|
|
// $Id$
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include "flaim.h"
|
|
#include "flm_lutl.h"
|
|
#include "gigatest.h"
|
|
|
|
// Columns/Rows where things go on the screen.
|
|
|
|
#define LABEL_COLUMN 5
|
|
#define DATA_COLUMN 35
|
|
|
|
#define MAX_CACHE_ROW 1
|
|
#define USED_CACHE_ROW 2
|
|
#define ITEMS_CACHED_ROW 3
|
|
#define DIRTY_CACHE_ROW 4
|
|
#define LOG_CACHE_ROW 5
|
|
#define FREE_CACHE_ROW 6
|
|
#define CP_STATE_ROW 7
|
|
#define DB_NAME_ROW 8
|
|
#define TOTAL_TO_LOAD_ROW 9
|
|
#define TRANS_SIZE_ROW 10
|
|
#define TOTAL_LOADED_ROW 11
|
|
#define ADDS_PER_SEC_CURRENT 12
|
|
#define ADDS_PER_SEC_OVERALL 13
|
|
#define ELAPSED_TIME_ROW 14
|
|
|
|
char gv_szDibName[ 200];
|
|
char gv_szDataDir[ 200];
|
|
char gv_szRflDir[ 200];
|
|
char gv_szDirectoryPath[ F_PATH_MAX_SIZE];
|
|
char gv_pszFileName[ F_FILENAME_SIZE];
|
|
FLMUINT gv_ui10Secs;
|
|
FLMUINT gv_ui1Sec;
|
|
IF_Thread * gv_pScreenThrd = NULL;
|
|
FLMUINT gv_uiCacheSize;
|
|
FLMUINT gv_uiBlockCachePercentage;
|
|
FLMUINT gv_uiMaxDirtyCache;
|
|
FLMUINT gv_uiLowDirtyCache;
|
|
FLMUINT gv_uiTotalToLoad;
|
|
FLMUINT gv_uiTransSize;
|
|
FLMUINT gv_uiTotalLoaded;
|
|
FLMUINT gv_ui10SecTotal;
|
|
FLMUINT gv_ui10SecStartTime;
|
|
FLMUINT gv_uiStartTime;
|
|
HFDB gv_hDb;
|
|
FLMBOOL gv_bShutdown;
|
|
FLMBOOL gv_bRunning;
|
|
FTX_SCREEN * gv_pScreen;
|
|
FTX_WINDOW * gv_pWindow;
|
|
F_MUTEX gv_hWindowMutex;
|
|
char * gv_pszTitle;
|
|
FLMUINT gv_uiNumCols;
|
|
FLMUINT gv_uiNumRows;
|
|
FLMUINT gv_uiMaxMemory;
|
|
FLMUINT gv_uiCPInterval;
|
|
FLMUINT gv_uiNumFields;
|
|
FLMUINT gv_uiPreallocSpace;
|
|
const char ** gv_ppszCurrGiven;
|
|
const char ** gv_ppszCurrFamily;
|
|
IF_Thread * gv_pIxManagerThrd;
|
|
FLMBOOL gv_bBatchMode;
|
|
FLMBOOL gv_bDisableDirectIO;
|
|
#ifdef FLM_NLM
|
|
FLMBOOL gv_bSynchronized;
|
|
#endif
|
|
|
|
const char * gv_pszGigaDictionary =
|
|
"0 @1@ field Person\n"
|
|
" 1 type text\n"
|
|
"0 @2@ field LastName\n"
|
|
" 1 type text\n"
|
|
"0 @3@ field FirstName\n"
|
|
" 1 type text\n"
|
|
"0 @4@ field Age\n"
|
|
" 1 type number\n"
|
|
"0 @100@ index LastFirst_IX\n"
|
|
" 1 language US\n"
|
|
" 1 key\n"
|
|
" 2 field 2\n"
|
|
" 3 required\n"
|
|
" 2 field 3\n"
|
|
" 3 required\n";
|
|
|
|
#define PERSON_TAG 1
|
|
#define LAST_NAME_TAG 2
|
|
#define FIRST_NAME_TAG 3
|
|
#define AGE_TAG 4
|
|
#define LAST_NAME_FIRST_NAME_IX 100
|
|
|
|
FLMUINT gigaGetInput(
|
|
const char * pszMsg1,
|
|
const char * pszMsg2,
|
|
FLMBOOL bMutexLocked = FALSE);
|
|
|
|
void gigaOutputErrMsg(
|
|
const char * pszErrMsg,
|
|
FLMBOOL bMutexLocked = FALSE);
|
|
|
|
void gigaOutputRcErr(
|
|
const char * pszWhat,
|
|
RCODE rc,
|
|
FLMBOOL bMutexLocked = FALSE);
|
|
|
|
void gigaOutputLabel(
|
|
FLMUINT uiRow,
|
|
const char * pszLabel,
|
|
FLMBOOL bMutexLocked = FALSE);
|
|
|
|
void gigaOutputStr(
|
|
FLMUINT uiRow,
|
|
const char * pszStr,
|
|
FLMBOOL bMutexLocked = FALSE);
|
|
|
|
void gigaOutputUINT(
|
|
FLMUINT uiRow,
|
|
FLMUINT uiNum,
|
|
FLMBOOL bMutexLocked = FALSE);
|
|
|
|
#ifdef FLM_NLM
|
|
extern "C"
|
|
{
|
|
void SynchronizeStart();
|
|
|
|
int nlm_main(
|
|
int ArgC,
|
|
char ** ArgV);
|
|
|
|
int atexit( void (*)( void ) );
|
|
}
|
|
|
|
void gigaCleanup( void);
|
|
#endif
|
|
|
|
void gigaInitGlobalVars( void);
|
|
|
|
void gigaShowHelp( void);
|
|
|
|
FLMBOOL gigaGetParams(
|
|
FLMINT iArgC,
|
|
const char ** ppszArgV);
|
|
|
|
FLMUINT gigaSeeIfQuit( void);
|
|
|
|
RCODE gigaStartTrans( void);
|
|
|
|
RCODE gigaMakeNewRecord(
|
|
FlmRecord ** ppRecord);
|
|
|
|
RCODE gigaCommitTrans( void);
|
|
|
|
void gigaUpdateMemInfo( void);
|
|
|
|
RCODE gigaLoadDatabase( void);
|
|
|
|
void gigaCheckpointDisplay( void);
|
|
|
|
RCODE FLMAPI gigaScreenThread(
|
|
IF_Thread * pThread);
|
|
|
|
RCODE gigaStartScreenThread( void);
|
|
|
|
/********************************************************************
|
|
Desc:
|
|
*********************************************************************/
|
|
#if defined( FLM_UNIX)
|
|
int main(
|
|
int iArgC,
|
|
char ** ppszArgV)
|
|
#elif defined( FLM_NLM)
|
|
int nlm_main(
|
|
int iArgC,
|
|
char ** ppszArgV)
|
|
#else
|
|
int __cdecl main(
|
|
int iArgC,
|
|
char ** ppszArgV)
|
|
#endif
|
|
{
|
|
int iRetCode = 0;
|
|
|
|
gigaInitGlobalVars();
|
|
|
|
#ifdef FLM_NLM
|
|
|
|
// Setup the routines to be called when the NLM exits itself
|
|
|
|
atexit( gigaCleanup);
|
|
|
|
#endif
|
|
|
|
if( RC_BAD( FlmStartup()))
|
|
{
|
|
iRetCode = 1;
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( FTXInit( gv_pszTitle, (FLMBYTE)80, (FLMBYTE)50,
|
|
FLM_BLUE, FLM_LIGHTGRAY, NULL, NULL)))
|
|
{
|
|
iRetCode = 1;
|
|
goto Exit;
|
|
}
|
|
|
|
FTXSetShutdownFlag( &gv_bShutdown);
|
|
|
|
if( RC_BAD( FTXScreenInit( gv_pszTitle, &gv_pScreen)))
|
|
{
|
|
iRetCode = 1;
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( FTXScreenInitStandardWindows( gv_pScreen, FLM_RED, FLM_WHITE,
|
|
FLM_BLUE, FLM_WHITE, FALSE, TRUE, gv_pszTitle, NULL, &gv_pWindow)))
|
|
{
|
|
iRetCode = 1;
|
|
goto Exit;
|
|
}
|
|
|
|
FTXWinGetCanvasSize( gv_pWindow, &gv_uiNumCols, &gv_uiNumRows);
|
|
|
|
if( RC_BAD( f_mutexCreate( &gv_hWindowMutex)))
|
|
{
|
|
iRetCode = 99;
|
|
goto Exit;
|
|
}
|
|
|
|
if( !gigaGetParams( iArgC, (const char **)ppszArgV))
|
|
{
|
|
iRetCode = 2;
|
|
goto Exit;
|
|
}
|
|
|
|
f_pathReduce( gv_szDibName, gv_szDirectoryPath, gv_pszFileName);
|
|
if( !gv_szDirectoryPath [0])
|
|
{
|
|
f_strcpy( gv_szDirectoryPath, ".");
|
|
}
|
|
|
|
if( RC_BAD( gigaLoadDatabase()))
|
|
{
|
|
iRetCode = 7;
|
|
goto Exit;
|
|
}
|
|
|
|
if( !gv_bBatchMode)
|
|
{
|
|
gigaOutputErrMsg( "Load complete");
|
|
}
|
|
|
|
Exit:
|
|
|
|
if( gv_hWindowMutex != F_MUTEX_NULL)
|
|
{
|
|
f_mutexDestroy( &gv_hWindowMutex);
|
|
}
|
|
|
|
FTXExit();
|
|
FlmShutdown();
|
|
|
|
#ifdef FLM_NLM
|
|
if (!gv_bSynchronized)
|
|
{
|
|
SynchronizeStart();
|
|
gv_bSynchronized = TRUE;
|
|
}
|
|
#endif
|
|
|
|
gv_bRunning = FALSE;
|
|
return( iRetCode);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Initialize global variables.
|
|
*********************************************************************/
|
|
void gigaInitGlobalVars( void)
|
|
{
|
|
gv_hDb = HFDB_NULL;
|
|
gv_bShutdown = FALSE;
|
|
gv_bRunning = TRUE;
|
|
gv_pScreen = NULL;
|
|
gv_pWindow = NULL;
|
|
gv_hWindowMutex = F_MUTEX_NULL;
|
|
gv_pszTitle = (char *)"GigaTest 1.0 for FLAIM";
|
|
gv_uiNumCols = 0;
|
|
gv_uiNumRows = 0;
|
|
gv_uiMaxMemory = 0;
|
|
gv_uiCPInterval = 0xFFFFFFFF;
|
|
gv_uiNumFields = 0;
|
|
gv_uiPreallocSpace = 0;
|
|
gv_ppszCurrGiven = &gv_pszGivenNames [0];
|
|
gv_ppszCurrFamily = &gv_pszFamilyNames [0];
|
|
gv_pIxManagerThrd = NULL;
|
|
gv_bBatchMode = FALSE;
|
|
gv_bDisableDirectIO = FALSE;
|
|
#ifdef FLM_NLM
|
|
gv_bSynchronized = FALSE;
|
|
#endif
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Show help for the gigaloader.
|
|
*********************************************************************/
|
|
void gigaShowHelp( void)
|
|
{
|
|
#ifdef FLM_NLM
|
|
if (!gv_bSynchronized)
|
|
{
|
|
SynchronizeStart();
|
|
gv_bSynchronized = TRUE;
|
|
}
|
|
#endif
|
|
f_mutexLock( gv_hWindowMutex);
|
|
FTXWinClear( gv_pWindow);
|
|
FTXWinPrintStr( gv_pWindow, "\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
"Parameters: [Number To Create] [Options]\n\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
"\nNumber To Create\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" Number of object to create (default = 100,000)\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
"\nOptions (may be specified anywhere on command line):\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -b = Run in batch mode.\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -c<n> = Cache (bytes) to use, 0=Use default mode\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -p<n> = Block cache percentage (0-100) to use (default 50)\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -i<n> = Checkpoint interval (seconds) to use.\n");
|
|
#ifdef FLM_NLM
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -n<DbName> = Database name (default = sys:\\_netware\\gigatest.db).\n");
|
|
#else
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -n<DbName> = Database name (default = gigatest.db).\n");
|
|
#endif
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -dr<Dir> = Directory where rfl files are located (default=same as db)\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -dd<Dir> = Directory where data files are located (default=same as db)\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -t<n> = Transaction Size (objects per transaction, default=100).\n");
|
|
#ifdef FLM_NLM
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -w = Wait to end to synchronize\n");
|
|
#endif
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -md<n> = Set maximum dirty cache (bytes), 0=Use default mode\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -ld<n> = Set low dirty cache (bytes), default=0\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" -? = A '?' anywhere in the command line will cause this help\n");
|
|
FTXWinPrintStr( gv_pWindow,
|
|
" screen to be displayed, with or without the leading '-'.\n");
|
|
f_mutexUnlock( gv_hWindowMutex);
|
|
gigaOutputErrMsg( "");
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Get command line parameters.
|
|
*********************************************************************/
|
|
FLMBOOL gigaGetParams(
|
|
FLMINT iArgC,
|
|
const char ** ppszArgV)
|
|
{
|
|
FLMBOOL bOk = FALSE;
|
|
FLMUINT uiLoop;
|
|
const char * pszPtr;
|
|
FLMBOOL bHaveNumToLoad = FALSE;
|
|
#ifdef FLM_NLM
|
|
FLMBOOL bWaitToSync = FALSE;
|
|
#endif
|
|
char szMsg [100];
|
|
|
|
gv_uiCacheSize = 0;
|
|
gv_uiBlockCachePercentage = 50;
|
|
gv_uiMaxDirtyCache = 0;
|
|
gv_uiLowDirtyCache = 0;
|
|
gv_uiTotalToLoad = 100000;
|
|
gv_uiTransSize = 100;
|
|
gv_uiTotalLoaded = 0;
|
|
#ifdef FLM_NLM
|
|
f_strcpy( gv_szDibName, "sys:\\_netware\\gigatest.db");
|
|
#else
|
|
f_strcpy( gv_szDibName, "gigatest.db");
|
|
#endif
|
|
gv_szDataDir[ 0] = 0;
|
|
gv_szRflDir[ 0] = 0;
|
|
|
|
// If no parameters were entered, show a help screen.
|
|
|
|
if( iArgC < 2)
|
|
{
|
|
gigaShowHelp();
|
|
goto Exit;
|
|
}
|
|
|
|
uiLoop = 1;
|
|
while( uiLoop < (FLMUINT)iArgC)
|
|
{
|
|
pszPtr = ppszArgV [uiLoop];
|
|
|
|
// See if they specified an option
|
|
|
|
#ifdef FLM_UNIX
|
|
if( *pszPtr == '-')
|
|
#else
|
|
if( (*pszPtr == '-') || (*pszPtr == '/'))
|
|
#endif
|
|
{
|
|
pszPtr++;
|
|
if ((*pszPtr == 'c') || (*pszPtr == 'C'))
|
|
{
|
|
gv_uiCacheSize = f_atol( (pszPtr + 1));
|
|
}
|
|
else if ((*pszPtr == 'i') || (*pszPtr == 'I'))
|
|
{
|
|
gv_uiCPInterval = f_atol( (pszPtr + 1));
|
|
}
|
|
else if ((*pszPtr == 'p') || (*pszPtr == 'P'))
|
|
{
|
|
gv_uiBlockCachePercentage = f_atol( (pszPtr + 1));
|
|
}
|
|
else if ((*pszPtr == 'm') || (*pszPtr == 'M'))
|
|
{
|
|
pszPtr++;
|
|
if ((*pszPtr == 'd') || (*pszPtr == 'D'))
|
|
{
|
|
gv_uiMaxDirtyCache = f_atol( (pszPtr + 1));
|
|
}
|
|
}
|
|
else if ((*pszPtr == 'l') || (*pszPtr == 'L'))
|
|
{
|
|
pszPtr++;
|
|
if ((*pszPtr == 'd') || (*pszPtr == 'D'))
|
|
{
|
|
gv_uiLowDirtyCache = f_atol( (pszPtr + 1));
|
|
}
|
|
}
|
|
else if ((*pszPtr == 't') || (*pszPtr == 'T'))
|
|
{
|
|
gv_uiTransSize = f_atol( (pszPtr + 1));
|
|
}
|
|
else if ((*pszPtr == 'n') || (*pszPtr == 'N'))
|
|
{
|
|
f_strcpy( gv_szDibName, pszPtr + 1);
|
|
}
|
|
else if (*pszPtr == 'd' || *pszPtr == 'D')
|
|
{
|
|
if( f_stricmp( pszPtr, "dio") == 0)
|
|
{
|
|
gv_bDisableDirectIO = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pszPtr++;
|
|
if (*pszPtr == 'r' || *pszPtr == 'R')
|
|
{
|
|
f_strcpy( gv_szRflDir, pszPtr + 1);
|
|
}
|
|
else if (*pszPtr == 'd' || *pszPtr == 'D')
|
|
{
|
|
f_strcpy( gv_szDataDir, pszPtr + 1);
|
|
}
|
|
else
|
|
{
|
|
f_sprintf( szMsg, "Invalid option %s", (pszPtr - 1));
|
|
gigaOutputErrMsg( szMsg);
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
else if (f_stricmp( pszPtr, "B") == 0)
|
|
{
|
|
gv_bBatchMode = TRUE;
|
|
}
|
|
#ifdef FLM_NLM
|
|
else if (f_stricmp( pszPtr, "W") == 0)
|
|
{
|
|
bWaitToSync = TRUE;
|
|
}
|
|
#endif
|
|
else if (f_stricmp( pszPtr, "?") == 0 ||
|
|
f_stricmp( pszPtr, "HELP") == 0)
|
|
{
|
|
gigaShowHelp();
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
f_sprintf( szMsg, "Invalid option %s", pszPtr);
|
|
gigaOutputErrMsg( szMsg);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else if (f_stricmp( pszPtr, "?") == 0)
|
|
{
|
|
gigaShowHelp();
|
|
return( FALSE);
|
|
}
|
|
else if (!bHaveNumToLoad)
|
|
{
|
|
gv_uiTotalToLoad = f_atol( pszPtr);
|
|
bHaveNumToLoad = TRUE;
|
|
}
|
|
uiLoop++;
|
|
}
|
|
|
|
#ifdef FLM_NLM
|
|
if (!bWaitToSync && !gv_bSynchronized)
|
|
{
|
|
SynchronizeStart();
|
|
gv_bSynchronized = TRUE;
|
|
}
|
|
#endif
|
|
|
|
bOk = TRUE;
|
|
Exit:
|
|
return( bOk);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Checks to see if the user pressed ESCAPE to exit the loader.
|
|
Also updates the total loaded counter on the screen.
|
|
*********************************************************************/
|
|
FLMUINT gigaSeeIfQuit( void)
|
|
{
|
|
FLMUINT uiChar = 0;;
|
|
|
|
f_mutexLock( gv_hWindowMutex);
|
|
gigaOutputUINT( TOTAL_LOADED_ROW, gv_uiTotalLoaded, TRUE);
|
|
if (RC_OK( FTXWinTestKB( gv_pWindow)))
|
|
{
|
|
FTXWinInputChar( gv_pWindow, &uiChar);
|
|
if (uiChar == FKB_ESCAPE)
|
|
{
|
|
uiChar = gigaGetInput(
|
|
"ESCAPE pressed, quit? (ESC,Q,Y=Quit, other=continue): ",
|
|
NULL, TRUE);
|
|
switch (uiChar)
|
|
{
|
|
case 'Q':
|
|
case 'q':
|
|
case 'y':
|
|
case 'Y':
|
|
uiChar = FKB_ESCAPE;
|
|
break;
|
|
case FKB_ESCAPE:
|
|
break;
|
|
default:
|
|
uiChar = 0;
|
|
break;
|
|
}
|
|
}
|
|
else if( uiChar == 'i' || uiChar == 'I')
|
|
{
|
|
HFDB hDb;
|
|
|
|
f_threadDestroy( &gv_pIxManagerThrd);
|
|
if (RC_OK( FlmDbOpen( gv_szDibName, gv_szDataDir,
|
|
gv_szRflDir, 0, NULL, &hDb)))
|
|
{
|
|
f_threadCreate( &gv_pIxManagerThrd,
|
|
flstIndexManagerThread, "index_manager",
|
|
F_DEFAULT_THREAD_GROUP, 0, (void *)hDb);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (gv_bShutdown)
|
|
{
|
|
uiChar = FKB_ESCAPE;
|
|
}
|
|
|
|
f_mutexUnlock( gv_hWindowMutex);
|
|
return( uiChar);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Starts a transaction and does a few modifications that are
|
|
necessary at the beginning of a transaction.
|
|
*********************************************************************/
|
|
RCODE gigaStartTrans( void)
|
|
{
|
|
RCODE rc = NE_FLM_OK;
|
|
FLMUINT uiChar;
|
|
|
|
while( !gv_bShutdown)
|
|
{
|
|
if( RC_BAD( rc = FlmDbTransBegin( gv_hDb,
|
|
FLM_UPDATE_TRANS, FLM_NO_TIMEOUT)))
|
|
{
|
|
if( rc != FERR_MUST_WAIT_CHECKPOINT)
|
|
{
|
|
gigaOutputRcErr( "starting transaction", rc);
|
|
goto Exit;
|
|
}
|
|
|
|
f_yieldCPU();
|
|
|
|
if( (uiChar = gigaSeeIfQuit()) != 0)
|
|
{
|
|
if (uiChar == FKB_ESCAPE)
|
|
{
|
|
gigaOutputRcErr( "starting transaction", rc);
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc:
|
|
*********************************************************************/
|
|
RCODE gigaMakeNewRecord(
|
|
FlmRecord ** ppRecord)
|
|
{
|
|
RCODE rc = NE_FLM_OK;
|
|
FlmRecord * pRecord = NULL;
|
|
void * pvField;
|
|
|
|
if( *ppRecord && !(*ppRecord)->isReadOnly())
|
|
{
|
|
f_assert( (*ppRecord)->getRefCount() == 1);
|
|
pRecord = *ppRecord;
|
|
*ppRecord = NULL;
|
|
pRecord->clear();
|
|
}
|
|
else
|
|
{
|
|
if( (pRecord = f_new FlmRecord) == NULL)
|
|
{
|
|
rc = RC_SET( NE_FLM_MEM);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if( RC_BAD( rc = pRecord->insertLast( 0, PERSON_TAG,
|
|
FLM_TEXT_TYPE, NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = pRecord->insertLast( 1, FIRST_NAME_TAG,
|
|
FLM_TEXT_TYPE, &pvField)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = pRecord->setNative( pvField, *gv_ppszCurrGiven)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = pRecord->insertLast( 1, LAST_NAME_TAG,
|
|
FLM_TEXT_TYPE, &pvField)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = pRecord->setNative( pvField, *gv_ppszCurrFamily)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = pRecord->insertLast( 1, AGE_TAG,
|
|
FLM_NUMBER_TYPE, &pvField)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = pRecord->setUINT( pvField, f_getRandomUINT32( 1, 100))))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( *ppRecord)
|
|
{
|
|
(*ppRecord)->Release();
|
|
}
|
|
|
|
*ppRecord = pRecord;
|
|
pRecord = NULL;
|
|
|
|
gv_ppszCurrGiven++;
|
|
if( *gv_ppszCurrGiven == NULL)
|
|
{
|
|
gv_ppszCurrGiven = &gv_pszGivenNames [0];
|
|
gv_ppszCurrFamily++;
|
|
|
|
if (*gv_ppszCurrFamily == NULL)
|
|
{
|
|
gv_ppszCurrFamily = &gv_pszFamilyNames[0];
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
if( pRecord)
|
|
{
|
|
pRecord->Release();
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Commits the current transaction - fixes up the parent object to
|
|
point to the last child added before committing.
|
|
*********************************************************************/
|
|
RCODE gigaCommitTrans( void)
|
|
{
|
|
RCODE rc = NE_FLM_OK;
|
|
|
|
gigaOutputUINT( TOTAL_LOADED_ROW, gv_uiTotalLoaded);
|
|
|
|
// Commit the transaction.
|
|
|
|
if( RC_BAD( rc = FlmDbTransCommit( gv_hDb)))
|
|
{
|
|
gigaOutputRcErr( "committing transaction", rc);
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Update the memory information on the screen.
|
|
*********************************************************************/
|
|
void gigaCheckpointDisplay( void)
|
|
{
|
|
char szBuf[ 80];
|
|
CHECKPOINT_INFO cpInfo;
|
|
|
|
FlmDbGetConfig( gv_hDb, FDB_GET_CHECKPOINT_INFO, &cpInfo, NULL, NULL);
|
|
if (!cpInfo.bRunning)
|
|
{
|
|
f_strcpy( szBuf, "Idle ");
|
|
}
|
|
else
|
|
{
|
|
if (cpInfo.bForcingCheckpoint)
|
|
{
|
|
f_sprintf( szBuf, "Forcing (%ums) ",
|
|
(unsigned)cpInfo.uiRunningTime);
|
|
}
|
|
else
|
|
{
|
|
f_sprintf( szBuf, "Running (%ums) ",
|
|
(unsigned)cpInfo.uiRunningTime);
|
|
}
|
|
}
|
|
|
|
gigaOutputStr( CP_STATE_ROW, szBuf);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Update the memory information on the screen.
|
|
*********************************************************************/
|
|
void gigaUpdateMemInfo( void)
|
|
{
|
|
FLM_MEM_INFO MemInfo;
|
|
char szBuf [50];
|
|
|
|
FlmGetMemoryInfo( &MemInfo);
|
|
|
|
f_sprintf( (char *)szBuf, "Blk: %-10u Record: %-10u",
|
|
(unsigned)MemInfo.BlockCache.uiMaxBytes,
|
|
(unsigned)MemInfo.RecordCache.uiMaxBytes);
|
|
gigaOutputStr( MAX_CACHE_ROW, szBuf);
|
|
|
|
f_sprintf( (char *)szBuf, "Blk: %-10u Record: %-10u",
|
|
(unsigned)MemInfo.BlockCache.uiTotalBytesAllocated,
|
|
(unsigned)MemInfo.RecordCache.uiTotalBytesAllocated);
|
|
gigaOutputStr( USED_CACHE_ROW, szBuf);
|
|
|
|
f_sprintf( (char *)szBuf, "Blk: %-10u Record: %-10u",
|
|
(unsigned)MemInfo.BlockCache.uiCount,
|
|
(unsigned)MemInfo.RecordCache.uiCount);
|
|
gigaOutputStr( ITEMS_CACHED_ROW, szBuf);
|
|
|
|
f_sprintf( (char *)szBuf, "Cnt: %-10u Bytes : %-10u",
|
|
(unsigned)MemInfo.uiDirtyCount, (unsigned)MemInfo.uiDirtyBytes);
|
|
gigaOutputStr( DIRTY_CACHE_ROW, szBuf);
|
|
|
|
f_sprintf( (char *)szBuf, "Cnt: %-10u Bytes : %-10u",
|
|
(unsigned)MemInfo.uiLogCount, (unsigned)MemInfo.uiLogBytes);
|
|
gigaOutputStr( LOG_CACHE_ROW, szBuf);
|
|
|
|
f_sprintf( (char *)szBuf, "Cnt: %-10u Bytes : %-10u",
|
|
(unsigned)MemInfo.uiFreeCount,
|
|
(unsigned)MemInfo.uiFreeBytes);
|
|
gigaOutputStr( FREE_CACHE_ROW, szBuf);
|
|
|
|
gigaCheckpointDisplay();
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: This routine functions as a thread. It keeps the gigaload screen
|
|
up to date.
|
|
****************************************************************************/
|
|
RCODE FLMAPI gigaScreenThread(
|
|
IF_Thread * pThread)
|
|
{
|
|
FLMUINT uiCurrTime;
|
|
|
|
for (;;)
|
|
{
|
|
// See if we should shut down.
|
|
|
|
if( pThread->getShutdownFlag())
|
|
{
|
|
break;
|
|
}
|
|
|
|
uiCurrTime = FLM_GET_TIMER();
|
|
|
|
// Update the display
|
|
|
|
gigaUpdateMemInfo();
|
|
|
|
pThread->sleep( 1000);
|
|
}
|
|
|
|
return( FERR_OK);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Start the screen thread.
|
|
*********************************************************************/
|
|
RCODE gigaStartScreenThread( void)
|
|
{
|
|
RCODE rc = FERR_OK;
|
|
|
|
// Start the screen thread
|
|
|
|
if( RC_BAD( rc = f_threadCreate( &gv_pScreenThrd,
|
|
gigaScreenThread, "Gigaload Monitor")))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Shutdown the screen thread.
|
|
*********************************************************************/
|
|
void gigaStopScreenThread( void)
|
|
{
|
|
f_threadDestroy( &gv_pScreenThrd);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc:
|
|
*********************************************************************/
|
|
void gigaUpdateLoadTimes( void)
|
|
{
|
|
FLMUINT uiElapsedTime;
|
|
FLMUINT uiCurrTime;
|
|
FLMUINT uiSecs;
|
|
FLMUINT uiAddsPerSec;
|
|
char szElapsedTime [20];
|
|
|
|
uiCurrTime = FLM_GET_TIMER();
|
|
uiElapsedTime = FLM_ELAPSED_TIME( uiCurrTime, gv_ui10SecStartTime);
|
|
|
|
// Calculate and display the average for the last 10 seconds.
|
|
|
|
uiSecs = FLM_TIMER_UNITS_TO_SECS( uiElapsedTime);
|
|
uiAddsPerSec = (gv_uiTotalLoaded - gv_ui10SecTotal) / uiSecs;
|
|
|
|
f_mutexLock( gv_hWindowMutex);
|
|
gigaOutputUINT( ADDS_PER_SEC_CURRENT, uiAddsPerSec, TRUE);
|
|
|
|
gv_ui10SecTotal = gv_uiTotalLoaded;
|
|
gv_ui10SecStartTime = uiCurrTime;
|
|
|
|
// Calculate and display the overall average
|
|
|
|
uiElapsedTime = FLM_ELAPSED_TIME( uiCurrTime, gv_uiStartTime);
|
|
uiSecs = FLM_TIMER_UNITS_TO_SECS( uiElapsedTime);
|
|
uiAddsPerSec = gv_uiTotalLoaded / uiSecs;
|
|
|
|
gigaOutputUINT( ADDS_PER_SEC_OVERALL, uiAddsPerSec, TRUE);
|
|
|
|
f_sprintf( szElapsedTime, "%u:%02u:%02u",
|
|
(unsigned)uiSecs / 3600,
|
|
(unsigned)(uiSecs % 3600) / 60,
|
|
(unsigned)uiSecs % 60);
|
|
|
|
gigaOutputStr( ELAPSED_TIME_ROW, szElapsedTime, TRUE);
|
|
|
|
f_mutexUnlock( gv_hWindowMutex);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Loads the database with objects.
|
|
*********************************************************************/
|
|
RCODE gigaLoadDatabase( void)
|
|
{
|
|
RCODE rc = NE_FLM_OK;
|
|
FLMBOOL bTransActive = FALSE;
|
|
FLMBOOL bCommitTrans = FALSE;
|
|
FLMUINT uiObjsInTrans = 0;
|
|
FLMUINT uiChar = 0;
|
|
FLMUINT bSuspend = FALSE;
|
|
FlmRecord * pNewRec = NULL;
|
|
|
|
// Set cache size, if specified on command line.
|
|
|
|
if( gv_uiCacheSize)
|
|
{
|
|
if( RC_BAD( rc = FlmSetHardMemoryLimit( 0, FALSE, 0,
|
|
gv_uiCacheSize, 0)))
|
|
{
|
|
gigaOutputRcErr( "setting cache size", rc);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Set block cache percentage, if it is not default.
|
|
|
|
if( gv_uiBlockCachePercentage != 50)
|
|
{
|
|
if( RC_BAD( rc = FlmConfig( FLM_BLOCK_CACHE_PERCENTAGE,
|
|
(void *)gv_uiBlockCachePercentage, (void *)0)))
|
|
{
|
|
gigaOutputRcErr( "setting block cache percentage", rc);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Set the maximum and low dirty cache, if one was specified
|
|
|
|
if( gv_uiMaxDirtyCache)
|
|
{
|
|
if( RC_BAD( rc = FlmConfig( FLM_MAX_DIRTY_CACHE,
|
|
(void *)gv_uiMaxDirtyCache, (void *)gv_uiLowDirtyCache)))
|
|
{
|
|
gigaOutputRcErr( "setting maximum dirty cache", rc);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Set checkpoint interval, if one is specified.
|
|
|
|
if( gv_uiCPInterval != 0xFFFFFFFF)
|
|
{
|
|
if( RC_BAD( rc = FlmConfig( FLM_MAX_CP_INTERVAL,
|
|
(void *)gv_uiCPInterval, (void *)0)))
|
|
{
|
|
gigaOutputRcErr( "setting checkpoint interval", rc);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Enable/Disable direct I/O
|
|
|
|
if( RC_BAD( rc = FlmConfig( FLM_DIRECT_IO_STATE,
|
|
(void *)!gv_bDisableDirectIO, NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Create the database.
|
|
|
|
(void)FlmDbRemove( gv_szDibName, gv_szDataDir, gv_szRflDir, TRUE);
|
|
|
|
if( RC_BAD( rc = FlmDbCreate( gv_szDibName, gv_szDataDir, gv_szRflDir,
|
|
NULL, gv_pszGigaDictionary, NULL, &gv_hDb)))
|
|
{
|
|
gigaOutputRcErr( "creating database", rc);
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = FlmDbConfig( gv_hDb,
|
|
FDB_RFL_FOOTPRINT_SIZE, (void *)(512 * 1024 * 1024), NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = FlmDbConfig( gv_hDb,
|
|
FDB_RBL_FOOTPRINT_SIZE, (void *)(512 * 1024 * 1024), NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Create the display
|
|
|
|
gv_uiTotalLoaded = 0;
|
|
gv_ui10SecTotal = 0;
|
|
|
|
f_mutexLock( gv_hWindowMutex);
|
|
FTXWinClear( gv_pWindow);
|
|
f_mutexUnlock( gv_hWindowMutex);
|
|
|
|
gigaOutputLabel( MAX_CACHE_ROW, "Maximum Cache Size (bytes)");
|
|
gigaOutputLabel( USED_CACHE_ROW, "Cache Used (bytes)");
|
|
gigaOutputLabel( ITEMS_CACHED_ROW, "Cache Used (items)");
|
|
gigaOutputLabel( DIRTY_CACHE_ROW, "Dirty Cache (bytes)");
|
|
gigaOutputLabel( LOG_CACHE_ROW, "Log Cache (bytes)");
|
|
gigaOutputLabel( FREE_CACHE_ROW, "Free Cache (bytes)");
|
|
gigaOutputLabel( CP_STATE_ROW, "Checkpoint State");
|
|
|
|
gigaUpdateMemInfo();
|
|
|
|
gigaOutputLabel( DB_NAME_ROW, "Database Name");
|
|
gigaOutputStr( DB_NAME_ROW, gv_szDibName);
|
|
|
|
gigaOutputLabel( TOTAL_TO_LOAD_ROW, "Total To Load");
|
|
gigaOutputUINT( TOTAL_TO_LOAD_ROW, gv_uiTotalToLoad);
|
|
|
|
gigaOutputLabel( TRANS_SIZE_ROW, "Transaction Size");
|
|
gigaOutputUINT( TRANS_SIZE_ROW, gv_uiTransSize);
|
|
|
|
gigaOutputLabel( TOTAL_LOADED_ROW, "Total Loaded");
|
|
gigaOutputUINT( TOTAL_LOADED_ROW, gv_uiTotalLoaded);
|
|
|
|
gigaOutputLabel( ADDS_PER_SEC_CURRENT, "Adds/Sec. (10 secs)");
|
|
gigaOutputUINT( ADDS_PER_SEC_CURRENT, 0);
|
|
|
|
gigaOutputLabel( ADDS_PER_SEC_OVERALL, "Adds/Sec. (overall)");
|
|
gigaOutputUINT( ADDS_PER_SEC_OVERALL, 0);
|
|
|
|
gigaOutputLabel( ELAPSED_TIME_ROW, "Elapsed Time");
|
|
gigaOutputStr( ELAPSED_TIME_ROW, "<none>");
|
|
|
|
if( RC_BAD( rc = gigaStartScreenThread()))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
gv_ui10SecStartTime = gv_uiStartTime = FLM_GET_TIMER();
|
|
gv_ui10Secs = FLM_SECS_TO_TIMER_UNITS( 10);
|
|
gv_ui1Sec = FLM_SECS_TO_TIMER_UNITS( 1);
|
|
|
|
for( ;;)
|
|
{
|
|
// See if we have been told to shut down, or if the user
|
|
// has pressed escape.
|
|
|
|
if( gv_bShutdown)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Every 127 objects, see if character was pressed and update
|
|
// count on screen.
|
|
|
|
if( (gv_uiTotalLoaded & 0x7F) == 0)
|
|
{
|
|
f_yieldCPU();
|
|
|
|
if( (uiChar = gigaSeeIfQuit()) != 0)
|
|
{
|
|
if( uiChar == FKB_ESCAPE)
|
|
{
|
|
break;
|
|
}
|
|
else if( uiChar == 's' || uiChar == 'S')
|
|
{
|
|
bSuspend = TRUE;
|
|
}
|
|
}
|
|
|
|
// Check for other keyboard options
|
|
}
|
|
else if( (gv_uiTotalLoaded & 0x7) == 0)
|
|
{
|
|
FLMUINT uiElapsedTime;
|
|
FLMUINT uiCurrTime;
|
|
|
|
uiCurrTime = FLM_GET_TIMER();
|
|
|
|
// If at least 10 seconds have elapsed, redisplay the average
|
|
// rate values.
|
|
|
|
if( (uiElapsedTime = FLM_ELAPSED_TIME( uiCurrTime,
|
|
gv_ui10SecStartTime)) >= gv_ui10Secs)
|
|
{
|
|
gigaUpdateLoadTimes();
|
|
}
|
|
}
|
|
|
|
// Start a transaction, if one is not going.
|
|
|
|
if( !bTransActive)
|
|
{
|
|
if( bSuspend)
|
|
{
|
|
uiChar = gigaGetInput(
|
|
"Load suspended, press any character to continue loading: ",
|
|
NULL);
|
|
bSuspend = FALSE;
|
|
}
|
|
|
|
if( RC_BAD( rc = gigaStartTrans()))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
bTransActive = TRUE;
|
|
bCommitTrans = FALSE;
|
|
uiObjsInTrans = 0;
|
|
}
|
|
|
|
// Increment the load counters and determine if this will be the
|
|
// last object of the transaction.
|
|
|
|
gv_uiTotalLoaded++;
|
|
uiObjsInTrans++;
|
|
|
|
if( uiObjsInTrans == gv_uiTransSize ||
|
|
gv_uiTotalLoaded == gv_uiTotalToLoad)
|
|
{
|
|
bCommitTrans = TRUE;
|
|
}
|
|
|
|
// Create a new object.
|
|
|
|
if( RC_BAD( rc = gigaMakeNewRecord( &pNewRec)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = FlmRecordAdd( gv_hDb, FLM_DATA_CONTAINER,
|
|
NULL, pNewRec, FLM_DONT_INSERT_IN_CACHE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Commit when we reach the transaction size or the total to load.
|
|
// NOTE: The bCommitTrans flag is set above.
|
|
|
|
if( bCommitTrans)
|
|
{
|
|
if( RC_BAD( rc = gigaCommitTrans()))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
bTransActive = FALSE;
|
|
}
|
|
|
|
// See if we are done.
|
|
|
|
if( gv_uiTotalLoaded == gv_uiTotalToLoad)
|
|
{
|
|
flmAssert( !bTransActive);
|
|
break;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
if( pNewRec)
|
|
{
|
|
pNewRec->Release();
|
|
}
|
|
|
|
if( bTransActive)
|
|
{
|
|
(void)FlmDbTransAbort( gv_hDb);
|
|
}
|
|
|
|
if( gv_hDb != HFDB_NULL)
|
|
{
|
|
FlmDbCheckpoint( gv_hDb, FLM_NO_TIMEOUT);
|
|
gigaStopScreenThread();
|
|
FlmDbClose( &gv_hDb);
|
|
|
|
// This will cause us to wait for the last checkpoint
|
|
// to finish.
|
|
|
|
(void)FlmConfig( FLM_CLOSE_FILE, (void *)gv_szDibName,
|
|
(void *)gv_szDataDir);
|
|
}
|
|
|
|
gigaUpdateLoadTimes();
|
|
gigaStopScreenThread();
|
|
f_threadDestroy( &gv_pIxManagerThrd);
|
|
|
|
return( rc);
|
|
}
|
|
|
|
#ifdef FLM_NLM
|
|
/****************************************************************************
|
|
Desc: This routine shuts down all threads in the NLM.
|
|
****************************************************************************/
|
|
void gigaCleanup( void)
|
|
{
|
|
gv_bShutdown = TRUE;
|
|
while( gv_bRunning)
|
|
{
|
|
f_yieldCPU();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
Desc: Displays two lines of message and gets the user's input.
|
|
*****************************************************************************/
|
|
FLMUINT gigaGetInput(
|
|
const char * pszMsg1,
|
|
const char * pszMsg2,
|
|
FLMBOOL bMutexLocked)
|
|
{
|
|
eColorType eSaveBack;
|
|
eColorType eSaveFore;
|
|
FLMUINT uiChar;
|
|
|
|
if (!bMutexLocked && gv_hWindowMutex != F_MUTEX_NULL)
|
|
{
|
|
f_mutexLock( gv_hWindowMutex);
|
|
}
|
|
|
|
// Get the background and foreground color so we can restore them.
|
|
|
|
FTXWinGetBackFore( gv_pWindow, &eSaveBack, &eSaveFore);
|
|
|
|
// Clear the last one or two lines on the screen
|
|
|
|
if (pszMsg2 && *pszMsg2)
|
|
{
|
|
FTXWinClearXY( gv_pWindow, 0, gv_uiNumRows - 2);
|
|
}
|
|
else
|
|
{
|
|
FTXWinClearXY( gv_pWindow, 0, gv_uiNumRows - 1);
|
|
}
|
|
|
|
// Change to WHITE on RED.
|
|
|
|
FTXWinSetBackFore( gv_pWindow, FLM_RED, FLM_WHITE);
|
|
|
|
// Display messages on last two lines of screen.
|
|
|
|
if (pszMsg2 && *pszMsg2)
|
|
{
|
|
FTXWinPrintStrXY( gv_pWindow, pszMsg1,
|
|
0, gv_uiNumRows - 2);
|
|
FTXWinPrintStrXY( gv_pWindow, pszMsg2,
|
|
0, gv_uiNumRows - 1);
|
|
}
|
|
else
|
|
{
|
|
FTXWinPrintStrXY( gv_pWindow, pszMsg1,
|
|
0, gv_uiNumRows - 1);
|
|
}
|
|
|
|
// Wait for user to press key.
|
|
|
|
for (;;)
|
|
{
|
|
if (gv_bShutdown)
|
|
{
|
|
uiChar = 0;
|
|
break;
|
|
}
|
|
if (RC_OK( FTXWinTestKB( gv_pWindow)))
|
|
{
|
|
FTXWinInputChar( gv_pWindow, &uiChar);
|
|
break;
|
|
}
|
|
f_sleep(50);
|
|
}
|
|
|
|
// Clear out last one or two lines of screen.
|
|
|
|
FTXWinSetBackFore( gv_pWindow, eSaveBack, eSaveFore);
|
|
|
|
if (pszMsg2 && *pszMsg2)
|
|
{
|
|
FTXWinClearXY( gv_pWindow, 0, gv_uiNumRows - 2);
|
|
}
|
|
else
|
|
{
|
|
FTXWinClearXY( gv_pWindow, 0, gv_uiNumRows - 1);
|
|
}
|
|
|
|
if (!bMutexLocked && gv_hWindowMutex != F_MUTEX_NULL)
|
|
{
|
|
f_mutexUnlock( gv_hWindowMutex);
|
|
}
|
|
|
|
return( uiChar);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Displays an error message.
|
|
*****************************************************************************/
|
|
void gigaOutputErrMsg(
|
|
const char * pszErrMsg,
|
|
FLMBOOL bMutexLocked)
|
|
{
|
|
(void)gigaGetInput( pszErrMsg, "Press any character to continue: ",
|
|
bMutexLocked);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Displays an error message with an RCODE.
|
|
*****************************************************************************/
|
|
void gigaOutputRcErr(
|
|
const char * pszWhat,
|
|
RCODE rc,
|
|
FLMBOOL bMutexLocked)
|
|
{
|
|
char szMsg [100];
|
|
|
|
f_sprintf( szMsg, "Error %s: %s (%04X)", pszWhat,
|
|
FlmErrorString( rc), (unsigned)rc);
|
|
gigaOutputErrMsg( szMsg, bMutexLocked);
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Output a label in the LABEL_COLUMN
|
|
*********************************************************************/
|
|
void gigaOutputLabel(
|
|
FLMUINT uiRow,
|
|
const char * pszLabel,
|
|
FLMBOOL bMutexLocked)
|
|
{
|
|
char szLabel [DATA_COLUMN - LABEL_COLUMN];
|
|
char * pszTmp;
|
|
FLMUINT uiNumDots = sizeof( szLabel) - 1;
|
|
|
|
f_memset( szLabel, '.', uiNumDots);
|
|
szLabel [uiNumDots] = 0;
|
|
|
|
pszTmp = &szLabel [0];
|
|
uiNumDots -= 2;
|
|
|
|
while( *pszLabel && uiNumDots)
|
|
{
|
|
*pszTmp++ = (FLMBYTE)(*pszLabel++);
|
|
uiNumDots--;
|
|
}
|
|
|
|
if( !bMutexLocked && gv_hWindowMutex != F_MUTEX_NULL)
|
|
{
|
|
f_mutexLock( gv_hWindowMutex);
|
|
}
|
|
|
|
FTXWinPrintStrXY( gv_pWindow, szLabel, LABEL_COLUMN, uiRow);
|
|
|
|
if( !bMutexLocked && gv_hWindowMutex != F_MUTEX_NULL)
|
|
{
|
|
f_mutexUnlock( gv_hWindowMutex);
|
|
}
|
|
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Output a string in the DATA_COLUMN
|
|
*********************************************************************/
|
|
void gigaOutputStr(
|
|
FLMUINT uiRow,
|
|
const char * pszStr,
|
|
FLMBOOL bMutexLocked)
|
|
{
|
|
if( !bMutexLocked && gv_hWindowMutex != F_MUTEX_NULL)
|
|
{
|
|
f_mutexLock( gv_hWindowMutex);
|
|
}
|
|
|
|
FTXWinPrintStrXY( gv_pWindow, pszStr, DATA_COLUMN, uiRow);
|
|
|
|
if( !bMutexLocked && gv_hWindowMutex != F_MUTEX_NULL)
|
|
{
|
|
f_mutexUnlock( gv_hWindowMutex);
|
|
}
|
|
}
|
|
|
|
/********************************************************************
|
|
Desc: Output a FLMUINT in the DATA_COLUMN
|
|
*********************************************************************/
|
|
void gigaOutputUINT(
|
|
FLMUINT uiRow,
|
|
FLMUINT uiNum,
|
|
FLMBOOL bMutexLocked)
|
|
{
|
|
char szBuf [20];
|
|
|
|
f_sprintf( szBuf, "%-10u", (unsigned)uiNum);
|
|
gigaOutputStr( uiRow, szBuf, bMutexLocked);
|
|
}
|