/** Primary entry function ***/ int main( int argc, char* argv[] ) { ReturnCode_t returnCode; // Create the master context Context_t context; // Zero the context memset( &context, 0, sizeof(Context_t) ); // Check the command line arguments for local and remote IP addresses and number of hyperperiods assert( argc == 4 ); /*** Initialize the FRODO subsystems ***/ SysEventInitialize( AllCategories, false, true, false ); PeripheralInitialize(); LogInitialize(); ErrorHandlerInitialize(); SchedInitialize( EarliestDeadlineFirst, ErrSchedulerHandler, 20.0, 1, &context ); UDPInitialize( ErrUDPHandler ); /*** Create message ports ***/ { // Set initial value of port message data_t data = { 1.0 }; CreateSamplingPort( "data", sizeof(data_t), Bidirectional, 0, &(context.msgPort), &returnCode ); WriteSamplingMessage( context.msgPort, &data, sizeof(data_t), &returnCode ); } /*** Create Tasks ***/ { // Create task with instances pfloat_t Task1_times[1] = { 4.0 }; SchedCreatePeriodicTask( "Task1", Task1_exec, &context.task1, 1.00, NoRestriction, 1, Task1_times ); } /*** Create Peripherals ***/ { pfloat_t send_times[1] = { 8.0 }; pfloat_t receive_times[1] = { 14.0 }; SyncExpectation syncExpects[2] = { { ExpectSend, 1, sizeof(data_t), 1, send_times, 2.0, context.msgPort, NULL }, { ExpectReceive, 1, sizeof(data_t), 1, receive_times, 2.0, context.msgPort, NULL } }; context.udpChannel = UDPCreateChannel( argv[1], argv[2], 21212, 2, syncExpects, 0, NULL, true, false, 2 ); } /*** Execute the schedule ***/ // Wait for the platform to wake up ( Platform Dependent ) NanoSleep( SCHEDULER_INITIALIZATION_WAIT ); // Execute the schedule SchedExecute( atoi(argv[3]) ); /*** Shutdown the application ***/ // If this returns we must shut everything down UDPShutdown( ); SchedShutdown( ); SysEventShutdown( NULL ); }
NTSTATUS #pragma prefast(suppress:28167) // Function changes IRQL SuspendTrigger( IN PINTERFACE Interface ) { PXENBUS_SUSPEND_CONTEXT Context = Interface->Context; KIRQL Irql; NTSTATUS status; KeRaiseIrql(DISPATCH_LEVEL, &Irql); LogPrintf(LOG_LEVEL_INFO, "SUSPEND: ====>\n"); SyncCapture(); SyncDisableInterrupts(); LogPrintf(LOG_LEVEL_INFO, "SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend ====>\n"); status = SchedShutdown(SHUTDOWN_suspend); LogPrintf(LOG_LEVEL_INFO, "SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend <==== (%08x)\n", status); if (NT_SUCCESS(status)) { PLIST_ENTRY ListEntry; Context->Count++; HypercallPopulate(); UnplugDevices(); for (ListEntry = Context->EarlyList.Flink; ListEntry != &Context->EarlyList; ListEntry = ListEntry->Flink) { PXENBUS_SUSPEND_CALLBACK Callback; Callback = CONTAINING_RECORD(ListEntry, XENBUS_SUSPEND_CALLBACK, ListEntry); Callback->Function(Callback->Argument); } } SyncEnableInterrupts(); // No lock is required here as the VM is single-threaded until // SyncRelease() is called. if (NT_SUCCESS(status)) { PLIST_ENTRY ListEntry; for (ListEntry = Context->LateList.Flink; ListEntry != &Context->LateList; ListEntry = ListEntry->Flink) { PXENBUS_SUSPEND_CALLBACK Callback; Callback = CONTAINING_RECORD(ListEntry, XENBUS_SUSPEND_CALLBACK, ListEntry); Callback->Function(Callback->Argument); } } SyncRelease(); LogPrintf(LOG_LEVEL_INFO, "SUSPEND: <====\n"); KeLowerIrql(Irql); return STATUS_SUCCESS; }