mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-18 22:03:16 +01:00
Updates to the atomvm port.
This commit is contained in:
@@ -6,11 +6,18 @@ License: BSD Revised
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Atomvm is a tiny virtual machine that can run on Windows inside an IDE with a
|
||||
debugger like Microsoft Visual C++ Express. The primary purpose of this virtual
|
||||
machine is for the evaluation of Real Time Operating Systems (like atomthreads)
|
||||
and the development and testing of modules for this Real Time Operating System
|
||||
in a user friendly environment.
|
||||
Atomvm is a tiny virtual machine that runs on Windows and can be debugged
|
||||
from an IDE like Microsoft Visual C++ Express. The primary purpose of this
|
||||
virtual machine is for the evaluation of Real Time Operating Systems like
|
||||
Atomthreads and the development and testing of programs for it on a Windows
|
||||
machine.
|
||||
|
||||
Atomvm makes use of the Windows API functions GetThreadContext() and
|
||||
SetThreadContext() to create multiple virtual contexts or threads inside a
|
||||
single Windows thread. Atomvm also simulates interrupts with an interrupt
|
||||
mask accessible from the Atomvm threads. External events can be queued as
|
||||
interrupts to Atomvm, for example a timer loop generating system timer tick
|
||||
interrupts for a Real Time Operating System ported to Atomvm.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
@@ -28,9 +35,6 @@ core system.
|
||||
|
||||
RUNNING THE TESTS
|
||||
|
||||
The test, main.c, is intentioned to stress the virtual machine as opposed to
|
||||
testing the Real Time Operating System. However, this test can also run the
|
||||
unit tests of atomthreads by using the preprocessor directive "UNIT_TESTS" and
|
||||
linking in the desired unit test into the project.
|
||||
The test, main.c, is intentioned to stress the virtual machine.
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ATOM_PORT_TESTS_H
|
||||
#define __ATOM_PORT_TESTS_H
|
||||
#ifndef __ATOMPORT_TEST_H__
|
||||
#define __ATOMPORT_TEST_H__
|
||||
|
||||
/* Include Atomthreads kernel API */
|
||||
#include "atom.h"
|
||||
@@ -56,3 +56,4 @@
|
||||
|
||||
#endif /* __ATOM_PORT_TESTS_H */
|
||||
|
||||
#endif /* __ATOMPORT_TEST_H__ */
|
||||
|
||||
@@ -53,7 +53,7 @@ static HANDLE cntrl_thread ;
|
||||
void
|
||||
atomvmRun ()
|
||||
{
|
||||
atomvmCtrlInit (&the_atomvm) ;
|
||||
atomvmCtrlCreate (&the_atomvm) ;
|
||||
cntrl_thread = CreateThread (NULL, 0, cntrl_thread_proc, (uint32_t*)the_atomvm, CREATE_SUSPENDED, NULL) ;
|
||||
ResumeThread (cntrl_thread) ;
|
||||
}
|
||||
@@ -85,7 +85,8 @@ thread_shell (void)
|
||||
* is first restored.
|
||||
*/
|
||||
// sei();
|
||||
atomvmExitCritical () ;
|
||||
//atomvmExitCritical () ;
|
||||
atomvmInterruptMask (0) ;
|
||||
|
||||
/* Call the thread entry point */
|
||||
if (curr_tcb && curr_tcb->entry_point)
|
||||
@@ -156,17 +157,3 @@ void archTimerTickIrqHandler ()
|
||||
/* Call the interrupt exit routine */
|
||||
atomIntExit(TRUE);
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
__enter_critical ()
|
||||
{
|
||||
return atomvmEnterCritical () ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__exit_critical (unsigned int isr)
|
||||
{
|
||||
atomvmExitCritical () ;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Kelvin Lawson. All rights reserved.
|
||||
* Copyright (c) 2012, Natie van Rooyen. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -32,19 +32,9 @@
|
||||
|
||||
#include "atomvm.h"
|
||||
|
||||
#define SYSTEM_MEMALIGN sizeof (unsigned int)
|
||||
#define SYSTEM_TICKS_PER_SEC 100
|
||||
|
||||
|
||||
typedef unsigned int uintptr_t ;
|
||||
typedef int intptr_t ;
|
||||
typedef unsigned int uint32_t ;
|
||||
typedef unsigned short uint16_t ;
|
||||
typedef unsigned char uint8_t ;
|
||||
typedef int int32_t ;
|
||||
typedef short int16_t ;
|
||||
typedef char int8_t ;
|
||||
|
||||
/* Size of each stack entry / stack alignment size (e.g. 32 bits) */
|
||||
#define STACK_ALIGN_SIZE sizeof(unsigned int)
|
||||
|
||||
/**
|
||||
* Architecture-specific types.
|
||||
@@ -52,15 +42,13 @@ typedef char int8_t ;
|
||||
* included above.
|
||||
*/
|
||||
#define POINTER void *
|
||||
#define ATOM_TLS HATOMVM_CONTEXT context ;
|
||||
|
||||
|
||||
/* Critical region protection */
|
||||
extern unsigned int __enter_critical() ;
|
||||
extern void __exit_critical(unsigned int) ;
|
||||
|
||||
#define CRITICAL_STORE unsigned int __atom
|
||||
#define CRITICAL_START() __atom = __enter_critical()
|
||||
#define CRITICAL_END() __exit_critical(__atom)
|
||||
#define CRITICAL_STORE unsigned int __atom_int_mask
|
||||
#define CRITICAL_START() __atom_int_mask = atomvmInterruptMask(1)
|
||||
#define CRITICAL_END() atomvmInterruptMask(__atom_int_mask)
|
||||
|
||||
#define ATOM_TLS HATOMVM_CONTEXT context ;
|
||||
|
||||
@@ -71,4 +59,4 @@ extern void archTimerTickIrqHandler () ;
|
||||
/* The instance of the atomvm for this port */
|
||||
extern HATOMVM the_atomvm ;
|
||||
|
||||
#endif /* __ATOM_PORT_H */
|
||||
#endif /* __ATOM_PORT_H__ */
|
||||
|
||||
@@ -39,18 +39,21 @@
|
||||
*
|
||||
* \b Function prototypes used for controlling the atom virtual machine: \n
|
||||
*
|
||||
* \li atomvmCtrlInit(): .
|
||||
* \li atomvmCtrlCreate(): .
|
||||
* \li atomvmCtrlRun(): .
|
||||
* \li atomvmCtrlIntRequest(): .
|
||||
* \li atomvmCtrlClose(): .
|
||||
*
|
||||
* \b Function prototypes for use by the atom virtual machine: \n
|
||||
*
|
||||
* \li atomvmExitCritical(): .
|
||||
* \li atomvmEnterCritical(): .
|
||||
* \li atomvmInterruptMask(): .
|
||||
* \li atomvmContextCreate(): .
|
||||
* \li atomvmContextSwitch(): .
|
||||
* \li atomvmContextDesrtroy(): .
|
||||
* \li atomvmWriteThreadId(): .
|
||||
* \li atomvmReadThreadId(): .
|
||||
* \li atomvmInterruptWait(): .
|
||||
* \li atomvmGetVmId(): .
|
||||
*
|
||||
* \b Function prototypes to be implemted in the atom virtual machine: \n
|
||||
*
|
||||
@@ -67,8 +70,6 @@
|
||||
|
||||
#define CONTEXT_VM (CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS)
|
||||
|
||||
#define ATOMVM_ATOMVM_PERF_COUNTER(patomvm, counter) (InterlockedIncrement(&patomvm->perf_counters.counter))
|
||||
|
||||
/* Data types */
|
||||
|
||||
/* Forward declarations */
|
||||
@@ -118,32 +119,6 @@ typedef struct ATOMVM_CALLBACK_CONTEXT_SWITCH_S {
|
||||
|
||||
} ATOMVM_CALLBACK_CONTEXT_SWITCH, *PATOMVM_CALLBACK_CONTEXT_SWITCH ;
|
||||
|
||||
/* ATOMVM_CALLBACK_IPI is the parameter for a ATOMVM_CALLBACK_F call
|
||||
that take as parameter a pointer to a ipi target and the isr to call */
|
||||
typedef struct ATOMVM_CALLBACK_IPI_S {
|
||||
|
||||
ATOMVM_CALLBACK callback ;
|
||||
|
||||
/* Parameters the callback function will operate on */
|
||||
volatile uint32_t target ;
|
||||
volatile uint32_t isr ;
|
||||
|
||||
} ATOMVM_CALLBACK_IPI, *PATOMVM_CALLBACK_IPI ;
|
||||
|
||||
typedef struct ATOMVM_PERF_COUNTERS_S {
|
||||
|
||||
/* Number of interrupt requests */
|
||||
uint32_t int_request ;
|
||||
|
||||
/* Number of service calls (context switches and
|
||||
context init from atom virtual machime) */
|
||||
uint32_t service_call ;
|
||||
|
||||
/* Total number of context switches */
|
||||
uint32_t context_switch ;
|
||||
|
||||
} ATOMVM_PERF_COUNTERS, *PATOMVM_PERF_COUNTERS ;
|
||||
|
||||
/* ATOMVM_CONTEXT saves the state of a context created by
|
||||
atomvmContextCreate() and sheduled by atomvmContextSwitch(). */
|
||||
typedef struct ATOMVM_CONTEXT_S {
|
||||
@@ -152,18 +127,16 @@ typedef struct ATOMVM_CONTEXT_S {
|
||||
during context initialization and context switches */
|
||||
CONTEXT context ;
|
||||
|
||||
/* When entering a critical section the critical_count is
|
||||
incremented for the context. Interrupts will only occur while
|
||||
the critical_count is zero. The functions atomvmExitCritical()
|
||||
and atomvmEnterCritical() will respectively decrement and
|
||||
increment the critical count */
|
||||
volatile uint32_t critical_count ;
|
||||
/* When entering a critical section the interrupt_mask is
|
||||
set for the context. Interrupts will only occur while
|
||||
the interrupt_mask is zero. */
|
||||
volatile uint32_t interrupt_mask ;
|
||||
uint32_t thread_id ;
|
||||
|
||||
} ATOMVM_CONTEXT, *PATOMVM_CONTEXT ;
|
||||
|
||||
/* ATOMVM defines the state of an instance to an atomvm. It is created
|
||||
by a call to atomvmCtrlInit(). */
|
||||
by a call to atomvmCtrlCreate(). */
|
||||
typedef struct ATOMVM_S {
|
||||
|
||||
uint32_t atomvm_id ;
|
||||
@@ -176,7 +149,6 @@ typedef struct ATOMVM_S {
|
||||
HANDLE atomvm_int ;
|
||||
HANDLE atomvm_int_complete ;
|
||||
HANDLE atomvm_close ;
|
||||
HANDLE atomvm_event ;
|
||||
|
||||
/* next ISR */
|
||||
volatile void (*isr)(void) ;
|
||||
@@ -191,21 +163,15 @@ typedef struct ATOMVM_S {
|
||||
and, return value for the current service call */
|
||||
PATOMVM_CALLBACK service_call ;
|
||||
|
||||
/* Context for startup, before any context was scheduled
|
||||
(workaround to not check everytime if the first context
|
||||
was already started) */
|
||||
/* Context for startup, before any context was scheduled */
|
||||
ATOMVM_CONTEXT atom_init_context ;
|
||||
|
||||
/* Performance counters */
|
||||
volatile ATOMVM_PERF_COUNTERS perf_counters ;
|
||||
|
||||
} ATOMVM, *PATOMVM ;
|
||||
|
||||
|
||||
/* Global declarations */
|
||||
volatile uint32_t g_atomvm_counter = 0 ;
|
||||
volatile DWORD g_atomvm_tls_idx ;
|
||||
PATOMVM g_vms[ATOMVM_MAX_VM] ;
|
||||
volatile uint32_t g_atomvm_id = 0 ;
|
||||
volatile DWORD g_atomvm_tls_idx ;
|
||||
|
||||
|
||||
/* Forward declaration for the atom virtual machine thread */
|
||||
@@ -214,57 +180,52 @@ static DWORD WINAPI vm_thread (LPVOID lpParameter) ;
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b atomvmCtrlInit
|
||||
* \b atomvmCtrlCreate
|
||||
*
|
||||
* This is an atomvm controll function used by a controlling thread
|
||||
* and must not be called from the atom virtual machine.
|
||||
*
|
||||
* Initializes the virtual machine.
|
||||
*
|
||||
* ToDo: More Error checking.
|
||||
*
|
||||
* @param[out] atomvm Handle to the virtual machine created.
|
||||
*
|
||||
* @return Zero on failure.
|
||||
*/
|
||||
uint32_t
|
||||
atomvmCtrlInit (HATOMVM *atomvm)
|
||||
atomvmCtrlCreate (HATOMVM *atomvm)
|
||||
{
|
||||
PATOMVM patomvm = 0 ;
|
||||
int32_t i ;
|
||||
|
||||
if (g_atomvm_counter < ATOMVM_MAX_VM) {
|
||||
patomvm = (PATOMVM) malloc (sizeof(struct ATOMVM_S)) ;
|
||||
|
||||
patomvm = (PATOMVM) malloc (sizeof(struct ATOMVM_S)) ;
|
||||
if (patomvm) {
|
||||
|
||||
if (patomvm) {
|
||||
memset (patomvm, 0, sizeof(struct ATOMVM_S)) ;
|
||||
|
||||
memset (patomvm, 0, sizeof(struct ATOMVM_S)) ;
|
||||
|
||||
patomvm->atomvm_id = InterlockedIncrement(&g_atomvm_counter) - 1 ;
|
||||
|
||||
if (patomvm->atomvm_id == 0) {
|
||||
g_atomvm_tls_idx = TlsAlloc () ;
|
||||
for (i=0; i<ATOMVM_MAX_VM; i++) {
|
||||
g_vms[i] = 0 ;
|
||||
}
|
||||
}
|
||||
g_vms[patomvm->atomvm_id] = patomvm ;
|
||||
|
||||
patomvm->atomvm_call = CreateEvent (NULL, TRUE, FALSE, 0) ;
|
||||
patomvm->atomvm_int = CreateEvent (NULL, TRUE, FALSE, 0) ;
|
||||
patomvm->atomvm_int_complete = CreateEvent (NULL, FALSE, TRUE, 0) ;
|
||||
patomvm->atomvm_close = CreateEvent (NULL, TRUE, FALSE, 0) ;
|
||||
patomvm->atomvm_event = CreateEvent (NULL, FALSE, FALSE, 0) ;
|
||||
|
||||
patomvm->vm_thread = CreateThread (NULL, 0, vm_thread, (void*)patomvm, CREATE_SUSPENDED, NULL) ;
|
||||
|
||||
patomvm->atom_init_context.critical_count = 1 ;
|
||||
patomvm->current_context = &patomvm->atom_init_context ;
|
||||
|
||||
*atomvm = (HATOMVM)patomvm ;
|
||||
patomvm->atomvm_id = InterlockedIncrement(&g_atomvm_id) - 1 ;
|
||||
|
||||
if (patomvm->atomvm_id == 0) {
|
||||
g_atomvm_tls_idx = TlsAlloc () ;
|
||||
}
|
||||
|
||||
patomvm->atomvm_call = CreateEvent (NULL, TRUE, FALSE, 0) ;
|
||||
patomvm->atomvm_int = CreateEvent (NULL, TRUE, FALSE, 0) ;
|
||||
patomvm->atomvm_int_complete = CreateEvent (NULL, FALSE, TRUE, 0) ;
|
||||
patomvm->atomvm_close = CreateEvent (NULL, TRUE, FALSE, 0) ;
|
||||
|
||||
ATOMVM_ASSERT(patomvm->atomvm_call && patomvm->atomvm_int && patomvm->atomvm_int_complete &&
|
||||
patomvm->atomvm_close, _T("ResumeThread failed")) ;
|
||||
|
||||
patomvm->vm_thread = CreateThread (NULL, 0, vm_thread, (void*)patomvm, CREATE_SUSPENDED, NULL) ;
|
||||
|
||||
ATOMVM_ASSERT(patomvm->vm_thread, _T("CreateThread failed")) ;
|
||||
|
||||
patomvm->atom_init_context.interrupt_mask = 1 ;
|
||||
patomvm->current_context = &patomvm->atom_init_context ;
|
||||
|
||||
*atomvm = (HATOMVM)patomvm ;
|
||||
|
||||
}
|
||||
|
||||
return patomvm != 0 ;
|
||||
@@ -275,16 +236,13 @@ atomvmCtrlInit (HATOMVM *atomvm)
|
||||
* \ingroup atomvm
|
||||
* \b atomvmCtrlRun
|
||||
*
|
||||
* This is an atomvm controll function used by a controlling thread
|
||||
* and must not be called from the atom virtual machine.
|
||||
*
|
||||
* After a call to atomvmCtrlInit this function start the atom virtual machine.
|
||||
* After a call to atomvmCtrlCreate this function start the atom virtual machine.
|
||||
* The calling thread will be used to manage interrupts and service calls in
|
||||
* the virtual machine. This function will not return untill atomvmCtrlClose
|
||||
* is called.
|
||||
*
|
||||
* @param[in] atomvm Handle to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[in] flags Reserved for later use.
|
||||
* @param[in] atomvm Handle to the virtual machine created by atomvmCtrlCreate.
|
||||
* @param[in] flags not used.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
@@ -299,9 +257,7 @@ atomvmCtrlRun (HATOMVM atomvm, uint32_t flags)
|
||||
#if defined DEBUG || defined _DEBUG
|
||||
BOOL tls_res =
|
||||
#endif
|
||||
TlsSetValue (g_atomvm_tls_idx, (void*) atomvm) ;
|
||||
|
||||
|
||||
TlsSetValue (g_atomvm_tls_idx, (void*) atomvm) ;
|
||||
ATOMVM_ASSERT(tls_res, _T("TlsSetValue failed")) ;
|
||||
|
||||
ResumeThread (patomvm->vm_thread) ;
|
||||
@@ -316,8 +272,6 @@ atomvmCtrlRun (HATOMVM atomvm, uint32_t flags)
|
||||
|
||||
if (wait_object == WAIT_OBJECT_0) {
|
||||
|
||||
ATOMVM_ATOMVM_PERF_COUNTER(patomvm, service_call) ;
|
||||
|
||||
service_call = patomvm->service_call ;
|
||||
while (!service_call->lock) {
|
||||
SwitchToThread () ;
|
||||
@@ -336,25 +290,23 @@ atomvmCtrlRun (HATOMVM atomvm, uint32_t flags)
|
||||
ResetEvent (patomvm->atomvm_call) ;
|
||||
res = ResumeThread (patomvm->vm_thread) ;
|
||||
ATOMVM_ASSERT(res == 1 , _T("ResumeThread failed")) ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
else if (wait_object == WAIT_OBJECT_0 + 1) {
|
||||
|
||||
if (patomvm->current_context->critical_count == 0) {
|
||||
if (patomvm->current_context->interrupt_mask == 0) {
|
||||
|
||||
while ((res = SuspendThread (patomvm->vm_thread)) == (DWORD)-1) ;
|
||||
ATOMVM_ASSERT(res == 0 , _T("SuspendThread failed")) ;
|
||||
#if (_WIN32_WINNT >= 0x0600)
|
||||
/*
|
||||
This is used for multi processor machines to ensure the thread
|
||||
is stopped before executing the next instruction. */
|
||||
is stopped before executing the next instruction. Set
|
||||
_WIN32_WINNT < 0x0600 if you are running Windows XP */
|
||||
FlushProcessWriteBuffers ();
|
||||
#endif
|
||||
if (patomvm->current_context->critical_count == 0) {
|
||||
|
||||
ATOMVM_ATOMVM_PERF_COUNTER(patomvm, int_request) ;
|
||||
if (patomvm->current_context->interrupt_mask == 0) {
|
||||
|
||||
patomvm->status_isr++ ;
|
||||
patomvm->isr () ;
|
||||
@@ -404,11 +356,11 @@ atomvmCtrlRun (HATOMVM atomvm, uint32_t flags)
|
||||
* and must not be called from the atom virtual machine.
|
||||
*
|
||||
* Closes the virtual machine and release all memory and handles created
|
||||
* in atomvmCtrlInit.
|
||||
* in atomvmCtrlCreate.
|
||||
*
|
||||
* ToDo: this function was never tested.
|
||||
*
|
||||
* @param[in] atomvm Handle to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[in] atomvm Handle to the virtual machine created by atomvmCtrlCreate.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
@@ -432,7 +384,7 @@ atomvmCtrlClose (HATOMVM atomvm)
|
||||
CloseHandle (patomvm->atomvm_close) ;
|
||||
CloseHandle (patomvm->vm_thread) ;
|
||||
|
||||
TlsFree (g_atomvm_tls_idx) ;
|
||||
// TlsFree (g_atomvm_tls_idx) ;
|
||||
|
||||
free (atomvm) ;
|
||||
}
|
||||
@@ -446,9 +398,9 @@ atomvmCtrlClose (HATOMVM atomvm)
|
||||
* an isr it is already in the conrtext of the controll thread and the callback
|
||||
* routine is called directly.
|
||||
*
|
||||
* The atom virtual machine is suspended during the callback.
|
||||
* The atom virtual machine thread is suspended during the callback.
|
||||
*
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlCreate.
|
||||
* @param[in] callback Callback function.
|
||||
* @param[in/out] context Context the function will operate on.
|
||||
*
|
||||
@@ -483,12 +435,12 @@ invokeCallback (PATOMVM patomvm, ATOMVM_CALLBACK_F callback, PATOMVM_CALLBACK se
|
||||
/*
|
||||
* \b getAtomvm
|
||||
*
|
||||
* Get the atomvm instance for the calling thredd
|
||||
* Get the atomvm instance for the calling thread
|
||||
*
|
||||
* @return atomvm instance
|
||||
*/
|
||||
__inline PATOMVM
|
||||
getAtomvm ()
|
||||
getAtomvm (void)
|
||||
{
|
||||
PATOMVM patomvm = (PATOMVM) TlsGetValue (g_atomvm_tls_idx) ;
|
||||
|
||||
@@ -498,76 +450,29 @@ getAtomvm ()
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b atomvmExitCritical
|
||||
* \b atomvmInterruptMask
|
||||
*
|
||||
* This function is to be used by the atom virtual machine.
|
||||
*
|
||||
* This function will decrement the critical count for the current atomvm context.
|
||||
* When the critical count reaches zero, interrupts will be enabled again. Calling
|
||||
* this function from inside an isr has no effect.
|
||||
* This function will mask interrupts for the current atomvm context.
|
||||
*
|
||||
* @return Critical count before the function call.
|
||||
* @param[in] mask zero enables interrupts any other value masks interrupts.
|
||||
*
|
||||
* @return Interrupt mask before the function call.
|
||||
*/
|
||||
int32_t
|
||||
atomvmExitCritical ()
|
||||
atomvmInterruptMask (uint32_t mask)
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
int32_t count = 0;
|
||||
int32_t interrupts = 0;
|
||||
|
||||
if (patomvm->status_isr == 0) {
|
||||
count = InterlockedDecrement (&patomvm->current_context->critical_count) ;
|
||||
interrupts = InterlockedExchange (&patomvm->current_context->interrupt_mask, mask) ;
|
||||
}
|
||||
|
||||
return count ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b atomvmEnterCritical
|
||||
*
|
||||
* This function is to be used by the atom virtual machine.
|
||||
*
|
||||
* This function will increment the critical count for the current atomvm
|
||||
* context. Interrupts will be disabled when the critical count is not zero.
|
||||
* Calling this function from inside an isr has no effect.
|
||||
*
|
||||
* All threads are created with a critical count of 1.
|
||||
*
|
||||
*
|
||||
* @return Critical count before the function call.
|
||||
*/
|
||||
int32_t
|
||||
atomvmEnterCritical ()
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
int32_t count = 0 ;
|
||||
|
||||
if (patomvm->status_isr == 0) {
|
||||
count = InterlockedIncrement (&patomvm->current_context->critical_count) ;
|
||||
}
|
||||
|
||||
return count ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b atomvmCriticalCount
|
||||
*
|
||||
* Rerurns the critical cont of the current context.
|
||||
*
|
||||
* @return the critical cont of the current context.
|
||||
*/
|
||||
int32_t
|
||||
atomvmCriticalCount ()
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
|
||||
return patomvm->current_context->critical_count ;
|
||||
return interrupts ;
|
||||
}
|
||||
|
||||
|
||||
@@ -575,17 +480,17 @@ atomvmCriticalCount ()
|
||||
* \ingroup atomvm
|
||||
* \b atomvmCtrlIntRequest
|
||||
*
|
||||
* This is an atomvm controll function used by a controlling thread(s)
|
||||
* This is an atomvm controll function used by external threads
|
||||
* and must not be called from the atom virtual machine.
|
||||
*
|
||||
* This function requests an interrupt service routine to be called in the
|
||||
* context of the atom virtual machine.
|
||||
*
|
||||
* The call will return immediately after the interrupt was scheduled.
|
||||
* The call will block while a previously scheduled interrupt is in progress.
|
||||
*
|
||||
* @param[in] atomvm Handle to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[in] isr The address of the interrupt service routine. The routine must use
|
||||
* the default calling convention of the compiler.
|
||||
* @param[in] atomvm Handle to the virtual machine created by atomvmCtrlCreate.
|
||||
* @param[in] isr The address of the interrupt service routine.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
@@ -610,7 +515,7 @@ atomvmCtrlIntRequest (HATOMVM atomvm, uint32_t isr)
|
||||
*
|
||||
* The atom virtual machine is suspended while this function is called.
|
||||
*
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlCreate.
|
||||
* @param[out] context Context to be initialized.
|
||||
*
|
||||
* @return Zero on failure, try to call GetLastError().
|
||||
@@ -654,7 +559,7 @@ atomvmContextCreate (HATOMVM_CONTEXT* atomvm_context, uint32_t stack, uint32_t e
|
||||
|
||||
context_init.pcontext = new_context ;
|
||||
|
||||
new_context->critical_count = 1 ;
|
||||
new_context->interrupt_mask = 1 ;
|
||||
|
||||
res = invokeCallback (patomvm, callbackContextCreate, (PATOMVM_CALLBACK)&context_init) ;
|
||||
|
||||
@@ -676,7 +581,7 @@ atomvmContextCreate (HATOMVM_CONTEXT* atomvm_context, uint32_t stack, uint32_t e
|
||||
*
|
||||
* The atom virtual machine is suspended while this function is called.
|
||||
*
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlCreate.
|
||||
* @param[out] context Context to be scheduled.
|
||||
*
|
||||
* @return Zero on failure, try to call GetLastError().
|
||||
@@ -690,8 +595,6 @@ callbackContextSwitch (PATOMVM patomvm, PATOMVM_CALLBACK callback)
|
||||
CONTEXT* p_old_context = &context_switch->p_old_context->context ;
|
||||
CONTEXT* p_new_context = &context_switch->p_new_context->context ;
|
||||
|
||||
ATOMVM_ATOMVM_PERF_COUNTER(patomvm, context_switch) ;
|
||||
|
||||
if (p_old_context) {
|
||||
res1 = GetThreadContext (patomvm->vm_thread, p_old_context) ;
|
||||
ATOMVM_ASSERT(res1 , _T("GetThreadContext failed")) ;
|
||||
@@ -783,7 +686,7 @@ atomvmWriteThreadId (uint32_t thread_id)
|
||||
* @return thread_id
|
||||
*/
|
||||
uint32_t
|
||||
atomvmReadThreadId ()
|
||||
atomvmReadThreadId (void)
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
|
||||
@@ -796,103 +699,18 @@ atomvmReadThreadId ()
|
||||
* \b atomvmGetVmId
|
||||
*
|
||||
* Returns an identifier for the virtual machine. This is zero for the first
|
||||
* virtual machine created with atomvmCtrlInit(), 1 for the second and so on.
|
||||
* virtual machine created with atomvmCtrlCreate(), 1 for the second and so on.
|
||||
*
|
||||
* @return The atom vm ID
|
||||
*/
|
||||
uint32_t
|
||||
atomvmGetVmId ()
|
||||
atomvmGetVmId (void)
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
|
||||
return patomvm->atomvm_id ;
|
||||
}
|
||||
/**
|
||||
* \b callbackEventWait
|
||||
*
|
||||
* This function is invoked from the controll thread after a call to atomvmEventWait.
|
||||
*
|
||||
* The atom virtual machine is suspended while this function is called.
|
||||
*
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[out] context Context to be scheduled.
|
||||
*
|
||||
* @return Zero on failure, try to call GetLastError().
|
||||
*/
|
||||
uint32_t
|
||||
callbackEventWait (PATOMVM patomvm, PATOMVM_CALLBACK callback)
|
||||
{
|
||||
return WaitForSingleObject (patomvm->atomvm_event, INFINITE) == WAIT_OBJECT_0 ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b atomvmEventWait
|
||||
*
|
||||
* This function is to be used by the atom virtual machine.
|
||||
*
|
||||
* This function if for synchronization between multiple
|
||||
* atom vms.
|
||||
*
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
void
|
||||
atomvmEventWait ()
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
ATOMVM_CALLBACK callback ;
|
||||
|
||||
invokeCallback (patomvm, callbackEventWait, (PATOMVM_CALLBACK)&callback) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \b callbackEventSend
|
||||
*
|
||||
* This function is invoked from the controll thread after a call to atomvmEventSend.
|
||||
*
|
||||
* The atom virtual machine is suspended while this function is called.
|
||||
*
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[out] context Context to be scheduled.
|
||||
*
|
||||
* @return Zero on failure, try to call GetLastError().
|
||||
*/
|
||||
uint32_t
|
||||
callbackEventSend (PATOMVM patomvm, PATOMVM_CALLBACK callback)
|
||||
{
|
||||
int32_t i ;
|
||||
for (i=0; i<ATOMVM_MAX_VM; i++) {
|
||||
if (g_vms[i] && (g_vms[i] != patomvm)) {
|
||||
SetEvent (g_vms[i]->atomvm_event) ;
|
||||
}
|
||||
}
|
||||
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b atomvmEventSend
|
||||
*
|
||||
* This function is to be used by the atom virtual machine.
|
||||
*
|
||||
* This function if for synchronization between multiple
|
||||
* atom vms.
|
||||
*
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
void
|
||||
atomvmEventSend ()
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
ATOMVM_CALLBACK callback ;
|
||||
|
||||
invokeCallback (patomvm, callbackEventSend, (PATOMVM_CALLBACK)&callback) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \b callbackInterruptWait
|
||||
@@ -901,7 +719,7 @@ atomvmEventSend ()
|
||||
*
|
||||
* The atom virtual machine is suspended while this function is called.
|
||||
*
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlInit.
|
||||
* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlCreate.
|
||||
* @param[out] callback Callback parameter.
|
||||
*
|
||||
* @return Zero on failure, try to call GetLastError().
|
||||
@@ -926,7 +744,7 @@ callbackInterruptWait (PATOMVM patomvm, PATOMVM_CALLBACK callback)
|
||||
* @return void.
|
||||
*/
|
||||
void
|
||||
atomvmInterruptWait ()
|
||||
atomvmInterruptWait (void)
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
ATOMVM_CALLBACK callback ;
|
||||
@@ -934,66 +752,6 @@ atomvmInterruptWait ()
|
||||
invokeCallback (patomvm, callbackInterruptWait, (PATOMVM_CALLBACK)&callback) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b callbackScheduleIpi
|
||||
*
|
||||
* This function is invoked from the controll thread after a call to atomvmScheduleIpi().
|
||||
*
|
||||
* This function if for synchronization between multiple
|
||||
* atom vms.
|
||||
*
|
||||
* @param[in] target Target atomvm ID, less than ATOMVM_MAX_VM
|
||||
* @param[in] isr interrupt service routine
|
||||
*
|
||||
* @return Zero on failure, try to call GetLastError().
|
||||
*/
|
||||
uint32_t
|
||||
callbackScheduleIpi (PATOMVM patomvm, PATOMVM_CALLBACK callback)
|
||||
{
|
||||
PATOMVM_CALLBACK_IPI callback_ipi = (PATOMVM_CALLBACK_IPI)callback ;
|
||||
uint32_t res = 0 ;
|
||||
|
||||
if ((callback_ipi->target < ATOMVM_MAX_VM) &&
|
||||
(g_vms[callback_ipi->target] != patomvm) ) {
|
||||
|
||||
atomvmCtrlIntRequest ((HATOMVM)g_vms[callback_ipi->target], callback_ipi->isr) ;
|
||||
res = 1 ;
|
||||
|
||||
}
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b atomvmScheduleIpi
|
||||
*
|
||||
* This function is to be used by the atom virtual machine.
|
||||
*
|
||||
* This function if for synchronization between multiple
|
||||
* atom vms.
|
||||
*
|
||||
* @param[in] target Target atomvm ID
|
||||
* @param[in] isr interrupt service routine
|
||||
*
|
||||
* @return Zero on failure, the vm is not running.
|
||||
*/
|
||||
uint32_t
|
||||
atomvmScheduleIpi (uint32_t target, uintptr_t isr)
|
||||
{
|
||||
PATOMVM patomvm = getAtomvm () ;
|
||||
ATOMVM_CALLBACK_IPI callback ;
|
||||
|
||||
callback.target = target ;
|
||||
callback.isr = isr ;
|
||||
|
||||
return invokeCallback (patomvm, callbackScheduleIpi, (PATOMVM_CALLBACK)&callback) ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \b vm_thread
|
||||
|
||||
@@ -35,32 +35,26 @@
|
||||
* @authors Natie van Rooyen
|
||||
*
|
||||
* @section intro Introduction
|
||||
* Atomvm is a tiny virtual machine that can run on Windows inside an IDE with a
|
||||
* debugger like Microsoft Visual C++ Express. The primary purpose of this virtual
|
||||
* machine is for the evaluation of Real Time Operating Systems (like atomthreads)
|
||||
* and the development and testing of modules for this Real Time Operating System
|
||||
* in a user friendly environment.:
|
||||
* Atomvm is a tiny virtual machine that runs on Windows and can be debugged
|
||||
* from an IDE like Microsoft Visual C++ Express. The primary purpose of this
|
||||
* virtual machine is for the evaluation of Real Time Operating Systems (like
|
||||
* Atomthreads) and the development and testing of modules for this Real Time
|
||||
* Operating System on a Windows machine.
|
||||
*
|
||||
* Atomvm makes use of the Windows API functions GetThreadContext() and
|
||||
* SetThreadContext() to create multiple virtual contexts or threads inside a
|
||||
* single Windows thread. Atomvm also simulates interrupts with an interrupt
|
||||
* mask accessible from the Atomvm threads. External events can be queued as
|
||||
* interrupts to Atomvm, for example a timer loop generating system timer tick
|
||||
* interrupts for a Real Time Operating System ported to Atomvm.
|
||||
*
|
||||
* @section build Building The Source
|
||||
* To test this project, just add all the files from the "atomthreads/kernel"
|
||||
* directory and the "atomthreads/ports/atomvm" directory as well as the test
|
||||
* program main.c to your project. Add both the
|
||||
* before mentioned directories to the include paths of your project and compile. \n
|
||||
* Atomvm was designed for multi core systems but also runs fine on any single
|
||||
* core system.
|
||||
*
|
||||
* @section test Running The Test
|
||||
* The test, main.c, is intentioned to stress the virtual machine as opposed to
|
||||
* testing the Real Time Operating System. However, this test can also run the
|
||||
* unit tests of atomthreads by using the preprocessor directive "UNIT_TESTS" and
|
||||
* linking in the desired unit test into the project.
|
||||
* */
|
||||
|
||||
#ifndef __ATOMVM_H__
|
||||
#define __ATOMVM_H__
|
||||
|
||||
#include <crtdbg.h>
|
||||
#include "atomuser.h"
|
||||
#include "types.h"
|
||||
|
||||
|
||||
#if defined _DEBUG || defined DEBUG
|
||||
@@ -75,7 +69,7 @@
|
||||
/* Forward declarations */
|
||||
|
||||
/* This is an opaque handle to an instance of an atomvm created
|
||||
by a call to atomvmCtrlInit() */
|
||||
by a call to atomvmCtrlCreate() */
|
||||
typedef struct ATOMVM* HATOMVM ;
|
||||
|
||||
/* This is an opaque handle to an atomvm context created
|
||||
@@ -84,40 +78,33 @@ typedef struct ATOMVM_CONTEXT* HATOMVM_CONTEXT ;
|
||||
|
||||
|
||||
/* Function prototypes used for controlling the atom virtual machine */
|
||||
extern uint32_t atomvmCtrlInit (HATOMVM* atomvm) ;
|
||||
extern uint32_t atomvmCtrlCreate (HATOMVM* atomvm) ;
|
||||
extern void atomvmCtrlRun (HATOMVM atomvm, uint32_t flags) ;
|
||||
extern void atomvmCtrlIntRequest (HATOMVM atomvm, uintptr_t isr) ;
|
||||
extern void atomvmCtrlClose (HATOMVM atomvm) ;
|
||||
|
||||
/* Function prototypes for use by the atom virtual machine */
|
||||
extern int32_t atomvmExitCritical () ;
|
||||
extern int32_t atomvmEnterCritical () ;
|
||||
extern int32_t atomvmCriticalCount () ;
|
||||
/* Function prototypes for use by the atom virtual machine from within the
|
||||
call to __atomvmReset(). */
|
||||
extern int32_t atomvmInterruptMask (uint32_t mask) ;
|
||||
extern uint32_t atomvmContextCreate (HATOMVM_CONTEXT* context, uint32_t stack, uint32_t entry) ;
|
||||
extern uint32_t atomvmContextSwitch (HATOMVM_CONTEXT old_context, HATOMVM_CONTEXT new_context) ;
|
||||
extern void atomvmContextDesrtroy (HATOMVM_CONTEXT context) ;
|
||||
extern void atomvmWriteThreadId (uint32_t thread_id) ;
|
||||
extern uint32_t atomvmReadThreadId () ;
|
||||
/* Function prototypes for use by the atom virtual machine
|
||||
for synchronization with other running atom virtual machines */
|
||||
extern uint32_t atomvmGetVmId () ;
|
||||
extern void atomvmInterruptWait () ;
|
||||
extern void atomvmEventWait () ;
|
||||
extern void atomvmEventSend () ;
|
||||
extern uint32_t atomvmScheduleIpi (uint32_t target, uintptr_t isr) ;
|
||||
|
||||
|
||||
extern uint32_t atomvmReadThreadId (void) ;
|
||||
extern void atomvmInterruptWait (void) ;
|
||||
extern uint32_t atomvmGetVmId (void) ;
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b __atomvmReset
|
||||
*
|
||||
* Function prototype to be implemted in the atom virtual machine
|
||||
* Function prototype to be implemted as entry point for the atom virtual machine.
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
extern void __atomvmReset (void) ;
|
||||
|
||||
/**
|
||||
* \ingroup atomvm
|
||||
* \b __atomvmClose
|
||||
|
||||
@@ -1,270 +1,270 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "atom.h"
|
||||
#include "atomvm.h"
|
||||
#include "atomport.h"
|
||||
|
||||
|
||||
// #define UNIT_TESTS
|
||||
#ifdef UNIT_TESTS
|
||||
extern uint32_t test_start (void) ;
|
||||
#endif
|
||||
|
||||
#define TEST_THREADS 47
|
||||
|
||||
#define TEST_STACK_BYTE_SIZE 0x10000
|
||||
#define IDLE_STACK_BYTE_SIZE 0x10000
|
||||
#define MONITOR_STACK_BYTE_SIZE 0x10000
|
||||
|
||||
|
||||
|
||||
static unsigned char idle_stack[IDLE_STACK_BYTE_SIZE] ;
|
||||
static unsigned char monitor_stack[MONITOR_STACK_BYTE_SIZE] ;
|
||||
static unsigned char test_stack[TEST_THREADS+1][TEST_STACK_BYTE_SIZE] ;
|
||||
static unsigned int test_counter[TEST_THREADS+1] = {0} ;
|
||||
|
||||
static unsigned int test2_counter = 0 ;
|
||||
static unsigned int test3_counter = 0 ;
|
||||
static unsigned int test_isr_count = 0 ;
|
||||
|
||||
|
||||
static unsigned char test2_stack[TEST_STACK_BYTE_SIZE] ;
|
||||
static unsigned char test3_stack[TEST_STACK_BYTE_SIZE] ;
|
||||
static unsigned char test_idle_stack[TEST_STACK_BYTE_SIZE] ;
|
||||
|
||||
|
||||
static uint8_t test_prio[60] = {
|
||||
001,010,100,200,250, 200,200,200,200,200,
|
||||
150,150,150,150,150, 250,250,250,250,250,
|
||||
101,102,103,104,105, 202,204,206,208,210,
|
||||
150,150,150,150,150, 250,250,250,250,250,
|
||||
121,122,123,124,125, 061,063,065,067,061,
|
||||
150,150,150,150,150, 250,250,250,250,250
|
||||
};
|
||||
|
||||
static uint32_t test_interv[60] = {
|
||||
001,001,001,001,001, 002,003,004,005,006,
|
||||
015,015,015,015,015, 025,024,023,022,021,
|
||||
905,005,005,005,805, 050,051,052,053,054,
|
||||
015,015,015,015,015, 025,024,023,022,021,
|
||||
030,030,030,030,030, 070,071,072,073,474,
|
||||
005,006,007,007,001, 001,001,003,003,005
|
||||
};
|
||||
|
||||
|
||||
ATOM_TCB test_tcb[TEST_THREADS+1] ;
|
||||
ATOM_TCB monitor_tcb ;
|
||||
ATOM_TCB test2_tcb ;
|
||||
ATOM_TCB test3_tcb ;
|
||||
ATOM_TCB test_idle_tcb ;
|
||||
|
||||
DWORD WINAPI isr_thread_proc (LPVOID lpParameter) ;
|
||||
static HANDLE isr_thread_1 ;
|
||||
static HANDLE isr_thread_2 ;
|
||||
static HANDLE isr_thread_3 ;
|
||||
static HANDLE isr_thread_4 ;
|
||||
|
||||
void
|
||||
ipi_sr()
|
||||
{
|
||||
printf("ipi\r\n") ;
|
||||
}
|
||||
|
||||
void
|
||||
monitor_thread (uint32_t parm)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
int i ;
|
||||
int c = 0 ;
|
||||
ATOM_TCB *tcb ;
|
||||
static unsigned int idle_1 = 0, idle_2 = 0, int_count = 0 ;
|
||||
unsigned int delta_idle_1 , delta_idle_2 , delta_int_count ;
|
||||
|
||||
tcb = atomCurrentContext() ;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
||||
CRITICAL_START();
|
||||
|
||||
printf("Monitor # %04d (%08d)\n", c++, atomTimeGet()) ;
|
||||
printf("-------------------------\n") ;
|
||||
|
||||
for (i=0; i<TEST_THREADS/3; i++) {
|
||||
printf("Thr %.2d cnt %08d\t",i,test_counter[i]);
|
||||
printf("Thr %.2d cnt %08d\t",i+TEST_THREADS/3,test_counter[i+TEST_THREADS/3]);
|
||||
printf("Thr %.2d cnt %08d\n",i+TEST_THREADS*2/3,test_counter[i+TEST_THREADS*2/3]);
|
||||
}
|
||||
|
||||
delta_idle_1 = test2_counter - idle_1 ;
|
||||
delta_idle_2 = test3_counter - idle_2 ;
|
||||
delta_int_count = test_isr_count - int_count ;
|
||||
printf("\nIdle Threadd 1 Counter = %d %d %d\nIdle Theadrd 2 Counter = %d %d %d\nInterrupt Counter = %d %d %d",
|
||||
test2_counter, delta_idle_1, (unsigned int)(test2_counter / c),
|
||||
test3_counter, delta_idle_2, (unsigned int)(test3_counter / c),
|
||||
test_isr_count, delta_int_count, (unsigned int)(test_isr_count / c));
|
||||
printf ("\n\n") ;
|
||||
idle_1 = test2_counter ;
|
||||
idle_2 = test3_counter ;
|
||||
int_count = test_isr_count ;
|
||||
CRITICAL_END();
|
||||
//for (i=0; i<100;i++) {
|
||||
// atomvmInterruptWait () ;
|
||||
//}
|
||||
atomTimerDelay (150) ;
|
||||
//atomvmScheduleIpi (atomvmGetVmId(), (uint32_t) ipi_sr) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
test_thread (uint32_t parm)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
|
||||
for (;;) {
|
||||
|
||||
atomTimerDelay (test_interv[parm]) ;
|
||||
CRITICAL_START();
|
||||
test_counter[parm]++ ;
|
||||
CRITICAL_END();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
test2_thread (uint32_t parm)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
|
||||
for (;;) {
|
||||
|
||||
CRITICAL_START();
|
||||
test2_counter++ ;
|
||||
CRITICAL_END();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test3_thread(uint32_t parm)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
|
||||
for (;;) {
|
||||
|
||||
CRITICAL_START();
|
||||
test3_counter++ ;
|
||||
CRITICAL_END();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
void unit_test_thread(uint32_t parm)
|
||||
{
|
||||
unsigned int failures ;
|
||||
|
||||
failures = test_start () ;
|
||||
printf ("test_start %d failures\n", failures) ;
|
||||
|
||||
while(1) {
|
||||
|
||||
atomTimerDelay (100);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__atomvmReset ()
|
||||
{
|
||||
unsigned int i ;
|
||||
|
||||
atomOSInit(&idle_stack[IDLE_STACK_BYTE_SIZE - sizeof(unsigned int)], IDLE_STACK_BYTE_SIZE - sizeof(unsigned int)) ;
|
||||
#ifndef UNIT_TESTS
|
||||
|
||||
for (i=0; i< TEST_THREADS;i++) {
|
||||
atomThreadCreate ((ATOM_TCB *)&test_tcb[i], test_prio[i], test_thread, i, &test_stack[i][TEST_STACK_BYTE_SIZE - sizeof(unsigned int)], TEST_STACK_BYTE_SIZE - sizeof(unsigned int));
|
||||
}
|
||||
|
||||
atomThreadCreate ((ATOM_TCB *)&monitor_tcb, 50, monitor_thread, 0, &monitor_stack[(MONITOR_STACK_BYTE_SIZE) - sizeof(unsigned int)], MONITOR_STACK_BYTE_SIZE - sizeof(unsigned int));
|
||||
|
||||
atomThreadCreate ((ATOM_TCB *)&test2_tcb, 253, test2_thread, 0, &test2_stack[(TEST_STACK_BYTE_SIZE) - sizeof(unsigned int)], (TEST_STACK_BYTE_SIZE) - sizeof(unsigned int));
|
||||
atomThreadCreate ((ATOM_TCB *)&test3_tcb, 253, test3_thread, 0, &test3_stack[(TEST_STACK_BYTE_SIZE) - sizeof(unsigned int)], (TEST_STACK_BYTE_SIZE) - sizeof(unsigned int));
|
||||
#else
|
||||
|
||||
atomThreadCreate ((ATOM_TCB *)&test2_tcb, 16, unit_test_thread, 0, &test2_stack[(TEST_STACK_BYTE_SIZE) - sizeof(unsigned int)], (TEST_STACK_BYTE_SIZE) - sizeof(unsigned int));
|
||||
|
||||
#endif
|
||||
|
||||
atomOSStart() ;
|
||||
}
|
||||
|
||||
void
|
||||
__atomvmClose ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
test_isr ()
|
||||
{
|
||||
static int i = 0 ;
|
||||
test_isr_count++ ;
|
||||
if (i++==25) {
|
||||
//Sleep(3) ;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI
|
||||
isr_thread_proc (LPVOID lpParameter)
|
||||
{
|
||||
int i = 0 ;
|
||||
int x ;
|
||||
int y = rand() % 100 ;
|
||||
while (1) {
|
||||
atomvmCtrlIntRequest (the_atomvm, (uintptr_t)test_isr) ;
|
||||
if (i++==y) {
|
||||
x = rand() % 50 ;
|
||||
Sleep (x) ;
|
||||
y = rand() % 100 ;
|
||||
i = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
atomvmRun () ;
|
||||
|
||||
#ifndef UNIT_TESTS
|
||||
isr_thread_1 = CreateThread (NULL, 0, isr_thread_proc, 0, CREATE_SUSPENDED, NULL) ;
|
||||
isr_thread_2 = CreateThread (NULL, 0, isr_thread_proc, 0, CREATE_SUSPENDED, NULL) ;
|
||||
isr_thread_3 = CreateThread (NULL, 0, isr_thread_proc, 0, CREATE_SUSPENDED, NULL) ;
|
||||
isr_thread_4 = CreateThread (NULL, 0, isr_thread_proc, 0, CREATE_SUSPENDED, NULL) ;
|
||||
|
||||
ResumeThread (isr_thread_1) ;
|
||||
ResumeThread (isr_thread_2) ;
|
||||
ResumeThread (isr_thread_3) ;
|
||||
ResumeThread (isr_thread_4) ;
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
Sleep(1) ;
|
||||
atomvmCtrlIntRequest (the_atomvm, (uintptr_t)archTimerTickIrqHandler) ;
|
||||
}
|
||||
|
||||
}
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "atom.h"
|
||||
#include "atomvm.h"
|
||||
#include "atomport.h"
|
||||
|
||||
|
||||
// #define UNIT_TESTS
|
||||
#ifdef UNIT_TESTS
|
||||
extern uint32_t test_start (void) ;
|
||||
#endif
|
||||
|
||||
#define TEST_THREADS 47
|
||||
|
||||
#define TEST_STACK_BYTE_SIZE 0x10000
|
||||
#define IDLE_STACK_BYTE_SIZE 0x10000
|
||||
#define MONITOR_STACK_BYTE_SIZE 0x10000
|
||||
|
||||
|
||||
|
||||
static unsigned char idle_stack[IDLE_STACK_BYTE_SIZE] ;
|
||||
static unsigned char monitor_stack[MONITOR_STACK_BYTE_SIZE] ;
|
||||
static unsigned char test_stack[TEST_THREADS+1][TEST_STACK_BYTE_SIZE] ;
|
||||
static unsigned int test_counter[TEST_THREADS+1] = {0} ;
|
||||
|
||||
static unsigned int test2_counter = 0 ;
|
||||
static unsigned int test3_counter = 0 ;
|
||||
static unsigned int test_isr_count = 0 ;
|
||||
|
||||
|
||||
static unsigned char test2_stack[TEST_STACK_BYTE_SIZE] ;
|
||||
static unsigned char test3_stack[TEST_STACK_BYTE_SIZE] ;
|
||||
static unsigned char test_idle_stack[TEST_STACK_BYTE_SIZE] ;
|
||||
|
||||
|
||||
static uint8_t test_prio[60] = {
|
||||
001,010,100,200,250, 200,200,200,200,200,
|
||||
150,150,150,150,150, 250,250,250,250,250,
|
||||
101,102,103,104,105, 202,204,206,208,210,
|
||||
150,150,150,150,150, 250,250,250,250,250,
|
||||
121,122,123,124,125, 061,063,065,067,061,
|
||||
150,150,150,150,150, 250,250,250,250,250
|
||||
};
|
||||
|
||||
static uint32_t test_interv[60] = {
|
||||
001,001,001,001,001, 002,003,004,005,006,
|
||||
015,015,015,015,015, 025,024,023,022,021,
|
||||
905,005,005,005,805, 050,051,052,053,054,
|
||||
015,015,015,015,015, 025,024,023,022,021,
|
||||
030,030,030,030,030, 070,071,072,073,474,
|
||||
005,006,007,007,001, 001,001,003,003,005
|
||||
};
|
||||
|
||||
|
||||
ATOM_TCB test_tcb[TEST_THREADS+1] ;
|
||||
ATOM_TCB monitor_tcb ;
|
||||
ATOM_TCB test2_tcb ;
|
||||
ATOM_TCB test3_tcb ;
|
||||
ATOM_TCB test_idle_tcb ;
|
||||
|
||||
DWORD WINAPI isr_thread_proc (LPVOID lpParameter) ;
|
||||
static HANDLE isr_thread_1 ;
|
||||
static HANDLE isr_thread_2 ;
|
||||
static HANDLE isr_thread_3 ;
|
||||
static HANDLE isr_thread_4 ;
|
||||
|
||||
void
|
||||
ipi_sr()
|
||||
{
|
||||
printf("ipi\r\n") ;
|
||||
}
|
||||
|
||||
void
|
||||
monitor_thread (uint32_t parm)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
int i ;
|
||||
int c = 0 ;
|
||||
ATOM_TCB *tcb ;
|
||||
static unsigned int idle_1 = 0, idle_2 = 0, int_count = 0 ;
|
||||
unsigned int delta_idle_1 , delta_idle_2 , delta_int_count ;
|
||||
|
||||
tcb = atomCurrentContext() ;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
||||
CRITICAL_START();
|
||||
|
||||
printf("Monitor # %04d (%08d)\n", c++, atomTimeGet()) ;
|
||||
printf("-------------------------\n") ;
|
||||
|
||||
for (i=0; i<TEST_THREADS/3; i++) {
|
||||
printf("Thr %.2d cnt %08d\t",i,test_counter[i]);
|
||||
printf("Thr %.2d cnt %08d\t",i+TEST_THREADS/3,test_counter[i+TEST_THREADS/3]);
|
||||
printf("Thr %.2d cnt %08d\n",i+TEST_THREADS*2/3,test_counter[i+TEST_THREADS*2/3]);
|
||||
}
|
||||
|
||||
delta_idle_1 = test2_counter - idle_1 ;
|
||||
delta_idle_2 = test3_counter - idle_2 ;
|
||||
delta_int_count = test_isr_count - int_count ;
|
||||
printf("\nIdle Threadd 1 Counter = %d %d %d\nIdle Theadrd 2 Counter = %d %d %d\nInterrupt Counter = %d %d %d",
|
||||
test2_counter, delta_idle_1, (unsigned int)(test2_counter / c),
|
||||
test3_counter, delta_idle_2, (unsigned int)(test3_counter / c),
|
||||
test_isr_count, delta_int_count, (unsigned int)(test_isr_count / c));
|
||||
printf ("\n\n") ;
|
||||
idle_1 = test2_counter ;
|
||||
idle_2 = test3_counter ;
|
||||
int_count = test_isr_count ;
|
||||
CRITICAL_END();
|
||||
//for (i=0; i<100;i++) {
|
||||
// atomvmInterruptWait () ;
|
||||
//}
|
||||
atomTimerDelay (450) ;
|
||||
//atomvmScheduleIpi (atomvmGetVmId(), (uint32_t) ipi_sr) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
test_thread (uint32_t parm)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
|
||||
for (;;) {
|
||||
|
||||
atomTimerDelay (test_interv[parm]) ;
|
||||
CRITICAL_START();
|
||||
test_counter[parm]++ ;
|
||||
CRITICAL_END();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
test2_thread (uint32_t parm)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
|
||||
for (;;) {
|
||||
|
||||
CRITICAL_START();
|
||||
test2_counter++ ;
|
||||
CRITICAL_END();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test3_thread(uint32_t parm)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
|
||||
for (;;) {
|
||||
|
||||
CRITICAL_START();
|
||||
test3_counter++ ;
|
||||
CRITICAL_END();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
void unit_test_thread(uint32_t parm)
|
||||
{
|
||||
unsigned int failures ;
|
||||
|
||||
failures = test_start () ;
|
||||
printf ("test_start %d failures\n", failures) ;
|
||||
|
||||
while(1) {
|
||||
|
||||
atomTimerDelay (100);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__atomvmReset ()
|
||||
{
|
||||
unsigned int i ;
|
||||
|
||||
atomOSInit(&idle_stack[0], IDLE_STACK_BYTE_SIZE, 1) ;
|
||||
#ifndef UNIT_TESTS
|
||||
|
||||
for (i=0; i< TEST_THREADS;i++) {
|
||||
atomThreadCreate ((ATOM_TCB *)&test_tcb[i], test_prio[i], test_thread, i, &test_stack[i][0], TEST_STACK_BYTE_SIZE, 1);
|
||||
}
|
||||
|
||||
atomThreadCreate ((ATOM_TCB *)&monitor_tcb, 50, monitor_thread, 0, &monitor_stack[0], MONITOR_STACK_BYTE_SIZE, 1);
|
||||
|
||||
atomThreadCreate ((ATOM_TCB *)&test2_tcb, 253, test2_thread, 0, &test2_stack[0], TEST_STACK_BYTE_SIZE, 1);
|
||||
atomThreadCreate ((ATOM_TCB *)&test3_tcb, 253, test3_thread, 0, &test3_stack[0], TEST_STACK_BYTE_SIZE, 1);
|
||||
#else
|
||||
|
||||
atomThreadCreate ((ATOM_TCB *)&test2_tcb, 16, unit_test_thread, 0, &test2_stack[], TEST_STACK_BYTE_SIZE, 1);
|
||||
|
||||
#endif
|
||||
|
||||
atomOSStart() ;
|
||||
}
|
||||
|
||||
void
|
||||
__atomvmClose ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
test_isr ()
|
||||
{
|
||||
static int i = 0 ;
|
||||
test_isr_count++ ;
|
||||
if (i++==25) {
|
||||
//Sleep(3) ;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI
|
||||
isr_thread_proc (LPVOID lpParameter)
|
||||
{
|
||||
int i = 0 ;
|
||||
int x ;
|
||||
int y = rand() % 100 ;
|
||||
while (1) {
|
||||
atomvmCtrlIntRequest (the_atomvm, (uintptr_t)test_isr) ;
|
||||
if (i++==y) {
|
||||
x = rand() % 50 ;
|
||||
Sleep (x) ;
|
||||
y = rand() % 100 ;
|
||||
i = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
atomvmRun () ;
|
||||
|
||||
#ifndef UNIT_TESTS
|
||||
isr_thread_1 = CreateThread (NULL, 0, isr_thread_proc, 0, CREATE_SUSPENDED, NULL) ;
|
||||
isr_thread_2 = CreateThread (NULL, 0, isr_thread_proc, 0, CREATE_SUSPENDED, NULL) ;
|
||||
isr_thread_3 = CreateThread (NULL, 0, isr_thread_proc, 0, CREATE_SUSPENDED, NULL) ;
|
||||
isr_thread_4 = CreateThread (NULL, 0, isr_thread_proc, 0, CREATE_SUSPENDED, NULL) ;
|
||||
|
||||
ResumeThread (isr_thread_1) ;
|
||||
ResumeThread (isr_thread_2) ;
|
||||
ResumeThread (isr_thread_3) ;
|
||||
ResumeThread (isr_thread_4) ;
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
Sleep(1) ;
|
||||
atomvmCtrlIntRequest (the_atomvm, (uintptr_t)archTimerTickIrqHandler) ;
|
||||
}
|
||||
|
||||
}
|
||||
20
ports/atomvm/msvc/msvc.sln
Normal file
20
ports/atomvm/msvc/msvc.sln
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C++ Express 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc", "msvc.vcxproj", "{77095EB1-4988-4A04-8751-69C63C7C541B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{77095EB1-4988-4A04-8751-69C63C7C541B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{77095EB1-4988-4A04-8751-69C63C7C541B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{77095EB1-4988-4A04-8751-69C63C7C541B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{77095EB1-4988-4A04-8751-69C63C7C541B}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
102
ports/atomvm/msvc/msvc.vcxproj
Normal file
102
ports/atomvm/msvc/msvc.vcxproj
Normal file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{77095EB1-4988-4A04-8751-69C63C7C541B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>msvc</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(MSBuildProjectDirectory)/../../../kernel;$(MSBuildProjectDirectory)/..;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(MSBuildProjectDirectory)/..;$(MSBuildProjectDirectory)/../../../kernel;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\kernel\atom.h" />
|
||||
<ClInclude Include="..\..\..\kernel\atommutex.h" />
|
||||
<ClInclude Include="..\..\..\kernel\atomqueue.h" />
|
||||
<ClInclude Include="..\..\..\kernel\atomsem.h" />
|
||||
<ClInclude Include="..\..\..\kernel\atomtimer.h" />
|
||||
<ClInclude Include="..\atomport-tests.h" />
|
||||
<ClInclude Include="..\atomport.h" />
|
||||
<ClInclude Include="..\atomuser.h" />
|
||||
<ClInclude Include="..\atomvm.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\kernel\atomkernel.c" />
|
||||
<ClCompile Include="..\..\..\kernel\atommutex.c" />
|
||||
<ClCompile Include="..\..\..\kernel\atomqueue.c" />
|
||||
<ClCompile Include="..\..\..\kernel\atomsem.c" />
|
||||
<ClCompile Include="..\..\..\kernel\atomtimer.c" />
|
||||
<ClCompile Include="..\atomport.c" />
|
||||
<ClCompile Include="..\atomvm.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
67
ports/atomvm/msvc/msvc.vcxproj.filters
Normal file
67
ports/atomvm/msvc/msvc.vcxproj.filters
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="atomthreads">
|
||||
<UniqueIdentifier>{d05cbb5a-256f-4127-bd5b-c3bd69b3672c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="port">
|
||||
<UniqueIdentifier>{f30700d8-652d-477c-a4f2-d23e7784de50}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="atomvm">
|
||||
<UniqueIdentifier>{a4f641bc-296d-4546-a831-2e1d0d7e9242}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\kernel\atom.h">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\kernel\atommutex.h">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\kernel\atomqueue.h">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\kernel\atomsem.h">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\kernel\atomtimer.h">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\atomport.h">
|
||||
<Filter>port</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\atomport-tests.h">
|
||||
<Filter>port</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\atomuser.h">
|
||||
<Filter>port</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\atomvm.h">
|
||||
<Filter>atomvm</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\kernel\atomkernel.c">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\kernel\atommutex.c">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\kernel\atomqueue.c">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\kernel\atomsem.c">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\kernel\atomtimer.c">
|
||||
<Filter>atomthreads</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\atomport.c">
|
||||
<Filter>port</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="..\atomvm.c">
|
||||
<Filter>atomvm</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,63 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2010,Kelvin Lawson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#if 1
|
||||
#ifndef __ATOM_USER_H__
|
||||
#define __ATOM_USER_H__
|
||||
|
||||
|
||||
/* Portable uint8_t and friends not available from stdint.h on this platform */
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
#define SYSTEM_MEMALIGN sizeof (unsigned int)
|
||||
|
||||
|
||||
typedef unsigned int uintptr_t ;
|
||||
typedef int intptr_t ;
|
||||
typedef unsigned int uint32_t ;
|
||||
typedef unsigned short uint16_t ;
|
||||
typedef unsigned char uint8_t ;
|
||||
typedef int int32_t ;
|
||||
typedef short int16_t ;
|
||||
typedef char int8_t ;
|
||||
|
||||
|
||||
/**
|
||||
* Architecture-specific types.
|
||||
* Most of these are available from stdint.h on this platform, which is
|
||||
* included above.
|
||||
*/
|
||||
#define POINTER void *
|
||||
|
||||
|
||||
#define ATOM_TLS HATOMVM_CONTEXT context ;
|
||||
|
||||
|
||||
#endif /* __ATOM_USER_H__ */
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 2010,Kelvin Lawson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __ATOM_USER_H__
|
||||
#define __ATOM_USER_H__
|
||||
|
||||
|
||||
/* Portable uint8_t and friends not available from stdint.h on this platform */
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
#define SYSTEM_MEMALIGN sizeof (unsigned int)
|
||||
|
||||
|
||||
typedef unsigned int uintptr_t ;
|
||||
typedef int intptr_t ;
|
||||
typedef unsigned int uint32_t ;
|
||||
typedef unsigned short uint16_t ;
|
||||
typedef unsigned char uint8_t ;
|
||||
typedef int int32_t ;
|
||||
typedef short int16_t ;
|
||||
typedef char int8_t ;
|
||||
|
||||
|
||||
/**
|
||||
* Architecture-specific types.
|
||||
* Most of these are available from stdint.h on this platform, which is
|
||||
* included above.
|
||||
*/
|
||||
#define POINTER void *
|
||||
|
||||
|
||||
#define ATOM_TLS HATOMVM_CONTEXT context ;
|
||||
|
||||
|
||||
#endif /* __ATOM_USER_H__ */
|
||||
Reference in New Issue
Block a user