static void mdlUpdate(SimStruct *S, int_T tid) { UNUSED(tid); struct timeval tv; gettimeofday(&tv, NULL); double *wall_t0 = (double*) ssGetDWork(S,0); if (*wall_t0 == TIME_NOT_YET_SET) { // t0 not set yet, set it now. (note: used to set this in mdlStart, but there can be a big pause between mdlStart and the full simulation start) *wall_t0 = timevalToDouble(tv); return; } double wall_t = timevalToDouble(tv), simtime = ssGetT(S), realtime_factor = mxGetScalar(ssGetSFcnParam(S, 1)); double t_diff = (wall_t - *wall_t0)*realtime_factor - simtime; // mexPrintf("wall time: %f, sim time: %f, (scaled) diff: %f\n", wall_t-*wall_t0, simtime, t_diff); if (t_diff<0.0) { // then simtime > scaled wall_time timespec tosleep; tv = doubleToTimeval(-t_diff); tosleep.tv_sec = tv.tv_sec; tosleep.tv_nsec = tv.tv_usec * 1000; // mexPrintf("sleeping... %d sec, %d nsec\n", tosleep.tv_sec, tosleep.tv_nsec); nanosleep(&tosleep, NULL); } else if (t_diff>1.0) { // then I'm behind by more than 1 second mexPrintf("at time %f, I'm behind by %f sec\n", simtime, t_diff); ssSetErrorStatus(S, "Simulink is not keeping up with real time. Consider reducing demands on your ODE solver, or optimizing your code."); } }
int main ( int argc, char **argv) { assert(argc > 1); double d = atof(argv[1]); printf("double: %f\n", d); struct timeval t; doubleToTimeval(d, &t); printf("before add; secs: %d, usecs: %d\n", t.tv_sec, t.tv_usec); struct timeval t2; t2.tv_usec = 2; t.tv_usec += t2.tv_usec; printf("after add; secs: %d, usecs: %d\n", t.tv_sec, t.tv_usec); if ( t.tv_usec >= 1000000 ) { t.tv_sec++; t.tv_usec-=1000000; } printf("after clean; secs: %d, usecs: %d\n", t.tv_sec, t.tv_usec); return 0; }