ll_define_primitive_end /* ** Compile into code to generate a value for an exports vector. */ ll_define_primitive(pair, _ir_compile2_export, _2(self, ir), _0()) { ll_v x = ll_SELF; ll_v var = ll_car(x); ll_v type = var_type(x); ll_v index = var_index(x); ll_assert_ref(IR); /* slot ref */ if ( ll_EQ(type, ll_s(slot)) ) { /* Create a const containing the global var name */ index = ll_call(ll_o(_ir_const_index), _2(IR, var)); } else if ( ll_EQ(type, ll_s(glo)) ) { ll_abort("<pair>:%ir-compile2-export"); } /* undef export is a local from a car-pos sub lambda */ if ( ll_EQ(type, ll_undef) ) { ll_call_tail(ll_o(_ir_compile2), _3(ll_undef, IR, ll_f)); } else { ll_v emit_type = type; /* env_loc is an environment slot containing a locative */ if ( ll_EQ(type, ll_s(env_loc)) ) { emit_type = ll_s(env); } if ( ll_unbox_boolean(index) ) { ll_call(ll_o(_ir_emit_with_int), _3(IR, emit_type, index)); } else { ll_call(ll_o(_ir_emit), _2(IR, emit_type)); } /* ** arg and local values are stored directly into the exports vector. ** so put the value, not a locative to the arg or local in the exports vector. */ if ( ll_EQ(type, ll_s(arg)) || ll_EQ(type, ll_s(local)) || ll_EQ(type, ll_s(env_loc)) ) { ll_call_tail(ll_o(_ir_emit), _2(IR, ll_s(contents))); } } }
int main (int argc, char *argv[]) { DWORD sp1, sp2; struct ll_initparms parms; void *mbi; struct timespec time1, time2, time3, time4, time5; struct timespec time6, time7, time8, time9; int par[10]; int i, secs; DWORD oldt, t; sp1 = get_sp(); cli(); #ifdef PERIODIC parms.mode = LL_PERIODIC; parms.tick = T; #else parms.mode = LL_ONESHOT; #endif mbi = ll_init(); event_init(&parms); if (mbi == NULL) { message("Error in LowLevel initialization code...\n"); sti(); l1_exit(-1); } sti(); message("LowLevel started...\n"); /* cli(); */ NULL_TIMESPEC(&time1); NULL_TIMESPEC(&time2); NULL_TIMESPEC(&time3); NULL_TIMESPEC(&time4); NULL_TIMESPEC(&time5); NULL_TIMESPEC(&time6); NULL_TIMESPEC(&time7); NULL_TIMESPEC(&time8); NULL_TIMESPEC(&time9); ADDNANO2TIMESPEC(1000000, &time1); /* Time1: 1 ms */ ADDNANO2TIMESPEC(5000000, &time2); /* Time2: 5 ms */ ADDNANO2TIMESPEC(10000000, &time3); /* Time 3: 10 ms */ ADDNANO2TIMESPEC(3000000, &time4); /* Time 4: 3 ms */ ADDNANO2TIMESPEC(7500000, &time5); /* Time 5: 7.5 ms */ ADDNANO2TIMESPEC(7000000, &time6); /* Time 6: 7 ms */ ADDNANO2TIMESPEC(500000000, &time7); ADDNANO2TIMESPEC(500000000, &time7); ADDNANO2TIMESPEC(500000000, &time7); ADDNANO2TIMESPEC(500000000, &time7); ADDNANO2TIMESPEC(500000000, &time7); ADDNANO2TIMESPEC(500000000, &time7); /* Time 7: 6*500 ms = 3 Sec*/ ADDNANO2TIMESPEC(51700000, &time8); /* Time 8: 51.7 ms */ ADDNANO2TIMESPEC(51500000, &time9); /* Time 9: 51.5 ms */ cli(); t = ll_gettime(TIME_NEW, NULL); sti(); for (i = 0; i < 10; i++) { par[i] = i + 1; } canEnd = 0; cli(); event_post(time1, evtHandler, &(par[0])); event_post(time2, evtHandler, &(par[1])); event_post(time3, evtHandler, &(par[2])); event_post(time4, evtHandler, &(par[3])); event_post(time5, evtHandler, &(par[4])); i = event_post(time6, evtHandler, &(par[5])); event_post(time7, evtHandler, &(par[6])); event_post(time8, evtHandler, &(par[7])); event_post(time9, evtHandler, &(par[8])); event_delete(i); event_post(time5, evtHandler, &(par[5])); message("Now time is %lu\n", t); secs = 0; oldt = 0; canEnd = 0; while((canEnd == 0) && (secs < 6)) { cli(); t = ll_gettime(TIME_NEW, NULL); sti(); if (t < oldt) { error("Time goes back???\n"); message("ARGGGGG! %lu %lu\n", t, oldt); ll_abort(100); } oldt = t; if ((t / 1000000) > secs) { secs++; message(" %d %lu\n", secs, t); } } cli(); message("Can End detected\n"); ll_end(); sp2 = get_sp(); for (i = 1; i < 10; i++) { message("Event %d called at time %lu == %lu\n", id[i], t1[i], t2[i]); } message("End reached!\n"); message("Actual stack : %lx - ", sp2); message("Begin stack : %lx\n", sp1); message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-("); return 1; }
TIME ll_gettime(int mode, struct timespec *tsres) { DWORD res, tc; BYTE isr; struct timespec tmp; #if 1 if (activeEvent) { if (tsres != NULL) { PITSPEC2TIMESPEC(&globalCounter, tsres); } else { struct timespec tmp; PITSPEC2TIMESPEC(&globalCounter, &tmp); return TIMESPEC2USEC(&tmp); } return TIMESPEC2USEC(tsres); } #endif if (mode == TIME_PTICK) { if (timermode != LL_PERIODIC) { return 0; } res = TIMESPEC2USEC(&actTime); if (tsres != NULL) { memcpy(tsres, &actTime, sizeof(struct timespec)); } return res; } if (mode == TIME_NEW) { WORD tmp; tmp = pit_read(frc); ADDPITSPEC((WORD)(lastTime - tmp), &globalCounter); lastTime = tmp; if (tsres != NULL) { PITSPEC2TIMESPEC(&globalCounter, tsres); } return (PITSPEC2USEC(&globalCounter)); } if (mode == TIME_EXACT) { if (timermode == LL_PERIODIC) { memcpy(&tmp, &actTime, sizeof(struct timespec)); /* How much time has elapsed * from the last Tick Boundary? */ tc = pit_read(0); if (tc > pit_time_const) { error("LL Time Panic!!!\n"); ll_abort(1); } res = pit_time_const - tc; res *= ticksize; res /= pit_time_const; /* Detect tick boundary and adjust the time... */ outp(0x20, 0x0A); isr = inp(0x20); if ((isr & 1) && res < ((8*ticksize)/10)){ /* res += ticksize; ADDNANO2TIMESPEC(ticksize * 1000, &tmp); */ res = ticksize; } /* Sum the Tick time... */ ADDNANO2TIMESPEC(res * 1000, &tmp); res += TIMESPEC2USEC(&actTime); if (tsres != NULL) { memcpy(tsres, &tmp, sizeof(struct timespec)); } return res; } else { return 0; } } return 0; }