Click here to Skip to main content
15,893,790 members
Articles / Desktop Programming / Win32

Visual Modeling of Complex Reactive Systems with Harel UML StateCharts

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
8 Sep 2009LGPL310 min read 43.7K   692   35  
This article presents a commercial-grade cross-platform Harel UML StateChart Open-Source application framework named StateWizard for concurrent, distributed, and real-time reactive system development with simplicity, efficiency, and scalability.
/* ==============================================================================================================================
 * This notice must be untouched at all times.
 *
 * Copyright  IntelliWizard Inc. 
 * All rights reserved.
 * Web: http://www.intelliwizard.com
 * eMail: info@intelliwizard.com
 * LICENSE: Dual Licensing. 

Intelliwizard employs a dual licensing model that offers customers a choice of either our open source license or a commercial license. 
Our open source license is OSI-certified and permits use of UML StateWizard in open source projects or in applications 
that are not distributed to third parties. Our commercial license permits closed-source distribution of an application to third parties 
and provides business assurance.

This model gives customers significant benefits:

Open Source License

    * Huge user community
    * Very high code quality
    * Easier debugging and integration
    * Easy download and trial
    * No escrow issues
    * Freedom from vendor lock-in

Commercial License

    * Application source code stays private
    * Legal assurances, warranties and indemnification
    * Full-time, dedicated development team provides ongoing maintenance and development, documentation, testing
    * Single vendor to hold accountable


The our open source license permits you to use UML StateWizard at no charge under the condition that if you use the software 
in an application you redistribute, the complete source code for your application must be available and freely redistributable 
under reasonable conditions. If you do not want to release the source code for your application, you may purchase a license from Intelliwizard.

Intelliwizard recognizes the common open source licenses, including the GPL license, as open source licenses. In general, 
licenses recognized by opensource.org meet the Intelliwizard requirements of "freely redistributable under reasonable conditions."
==============================================================================================================================*/


/* ==============================================================================================================================
  -------------------
  Feature List:
  -------------------
  Process Management
  Thread Management
  Mutex
  Event Loop
  Clock
  Built-in Timer
  Thread Local Storage
 * ==============================================================================================================================*/
#ifndef _CROSS_PLATFORM_H_
#define _CROSS_PLATFORM_H_

#include <time.h>
#include <errno.h>

#include "sme.h"

#if defined SME_LINUX
	#include <string.h>
	#include <unistd.h>
	#include <pthread.h>
	#include <signal.h>
	#include <sys/time.h>
	#include <stdio.h>
	#include <stdlib.h>
	#include <linux/unistd.h>
	typedef pthread_t         XTHREADID;
	typedef pthread_t         XTHREADHANDLE;
	typedef pthread_mutex_t   XMUTEX; 
	typedef pthread_cond_t    XEVENT;

	#define XINFINITE 0xFFFFFFFF
	#define XWAIT_TIMEOUT     ETIMEDOUT
#elif defined SME_WIN32
	#include <windows.h>
	#include <winbase.h>
	#include <process.h>
	#include <shlwapi.h>
	#include <stdio.h>
	typedef DWORD             XTHREADID;
	typedef HANDLE            XTHREADHANDLE;
	typedef HANDLE            XMUTEX;
	typedef DWORD            XEVENT; // The thread ID for GetMessage()

	#define WM_EXT_EVENT_ID  0xBFFF
	
	#define XINFINITE INFINITE
	#define XWAIT_TIMEOUT     WAIT_TIMEOUT
	
	#define snprintf  _snprintf
	// If the compiler encounters the use of a deprecated identifier, a C4996 warning is thrown.
	#pragma warning(disable : 4996)
#endif 

/****************************************************************/
#ifdef __cplusplus   
extern "C" {
#endif

#ifdef SME_WIN32
	typedef unsigned (__stdcall *XTHREAD_PROC_T)(void*);
	void XCloseHandle(XTHREADHANDLE thread_handle);
	#define XCLOSE_HANDLE XCloseHandle
#else
	typedef void* (*XTHREAD_PROC_T)(void*);
	#define XCLOSE_HANDLE(x) 
#endif
	
int XCreateThread(XTHREAD_PROC_T start_routine, void *arg, XTHREADHANDLE *new_thread_handle);
void XEndThread(void);
XTHREADID XGetCurrentThreadId(void);
BOOL  XIsThreadRunning(XTHREADHANDLE thread_handle);
int XWaitForThread(XTHREADHANDLE thread_handle);
int XSetThreadPriority(XTHREADHANDLE thread_handle, int nPriority);

BOOL XCreateProcess(const char* pProgramPath,int* ppid);
void XKillProcess(int pid);
BOOL XIsProcessRunning(int pid);


void XSleep(unsigned int milliseconds);
int XGetTick(void);

/* #define STR_TIME_FMT		"%m/%d/%y %H:%M:%S" 
Note: You may change order of the %m/%d/%y for the month/day/year. Do not change the flags m d y H M S.*/
char* XGetCurrentTimeStr(char *szBuf, int nLen, const char* szFmt);
char* XGetTimeStr(time_t nTime, char *szBuf, int nLen, const char* szFmt);
char* XGetElapsedTimeStr(time_t nTime, char* szBuf, int nLen);


// A  mutex  is a MUTual EXclusion device, and is useful for protecting shared data structures from concurrent modifications, 
// and implementing critical sections and monitors.
// This Mutex object can be used to synchronize threads in the process only.

// In Linux, pthread_mutex_t is type of a structure.
int  XCreateMutex(XMUTEX *mutex_ptr);
int  XMutexLock(XMUTEX *mutex_ptr);
int  XMutexUnlock(XMUTEX *mutex_ptr);
int  XDestroyMutex(XMUTEX *mutex_ptr);


// A event/condition (short for condition variable) is a synchronization device that allows threads to suspend execution and relinquish  the  processors
// until  some  predicate  on shared data is satisfied. The basic operations on conditions are: signal the condition (when the predicate becomes true),
// wait for the condition, and suspending the thread execution until another thread signals the condition.

// This Event object can be used to synchronize threads in the process only.

typedef int (*XTHREAD_SAFE_ACTION_T)(void*p);
typedef BOOL (*XIS_CODITION_OK_T)(void*p);

int XCreateEvent(XEVENT *pEvent);
int XWaitForEvent(XEVENT *pEvent, XMUTEX *pMutex, XIS_CODITION_OK_T pIsConditionOK, void *pCondParam,
				  XTHREAD_SAFE_ACTION_T pAction, void *pActionParam);
int XSignalEvent(XEVENT *pEvent, XMUTEX *pMutex, XTHREAD_SAFE_ACTION_T pAction, void *pActionParam);
int XDestroyEvent(XEVENT *pEvent);

// Thread Local Storage
int XTlsAlloc(void);
BOOL XSetThreadContext(SME_THREAD_CONTEXT_PT p);
SME_THREAD_CONTEXT_PT XGetThreadContext(void);
BOOL XFreeThreadContext(SME_THREAD_CONTEXT_PT p);


/******************************************************************************************
*  Built-in Timer
******************************************************************************************/
typedef int (*SME_TIMER_PROC_T)(SME_OBJ_T *pDestObj, unsigned long nSequenceNum);

// On Linux platform, call the XInitTimer function at the time-out event trigger thread. 
// On time-out, the external event trigger thread posts SME_EVENT_TIMER to the state machine application thread,
// and then invokes the callback function installed by the XSetTimer function. 
int XInitTimer();
int XDestroyTimer();

/*
SmeSetTimer or SmeSetEventTimer function creates a timer. The timer is set for every nElapse mili-seconds. SmeSetTimer setup a function to be notified when the time-out value elapses.

If the function succeeds, the return value is a sequence number identifying the new timer. If an object receives a SME_EVENT_TIMER event from more than 1 timer, objects can identify which timer triggers the event through sequence number.

SmeSetEventTimer posts an SME event with the timer identifier in the nSequenceNum member of SME_EVENT_T structure, when the time-out value elapses.

The return value of the function is an ID to the new timer. An object can pass this handle to the SmeKillTimer function to destroy the timer. 

SmeSetTimer or SmeSetEventTimer function returns 0 if the function fails.

NOTE: The nTimeOut parameter for regular timers should be less than 0x80000000. Other values are reserved for the state built-in timers.
*/

#define SME_STATE_BUILT_IN_TIMEOUT_VAL(_Elapse)  (0x80000000  | _Elapse)
#define SME_GET_STATE_BUILT_IN_TIMEOUT_VAL(_Data) (_Data & 0x7FFFFFFF)
#define SME_IS_STATE_BUILT_IN_TIMEOUT_VAL(_Data)  (_Data & 0x80000000)

unsigned int XSetTimer(SME_OBJ_T *pDestObj, unsigned int nTimeOut, SME_TIMER_PROC_T pfnTimerFunc); 
unsigned int XSetEventTimer(SME_OBJ_T *pDestObj, unsigned  int nTimeOut); 
BOOL XKillTimer(unsigned int nSequenceNum);

/******************************************************************************************
*  Dynamic Memory Management
******************************************************************************************/
void* XEmptyMemAlloc(int nSize);
void XMemFree(void* p);


#ifdef __cplusplus
}
#endif 


#endif /* _CROSS_PLATFORM_H_ */

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions