diff --git a/src/component.c b/src/component.c index 1203592..6c84fd6 100644 --- a/src/component.c +++ b/src/component.c @@ -95,7 +95,7 @@ bool nn_invokeComponentMethod(nn_component *component, const char *name) { if(strcmp(method.name, name) == 0) { nn_callCost(component->computer, NN_CALL_COST); if(!method.direct) { - nn_busySleep(NN_INDIRECT_CALL_LATENCY); + nn_triggerIndirect(component->computer); } method.method(component->statePtr, method.userdata, component, component->computer); return true; @@ -105,3 +105,13 @@ bool nn_invokeComponentMethod(nn_component *component, const char *name) { // no such method return false; } + +void nn_simulateBufferedIndirect(nn_component *component, double amount, double amountPerTick) { + double maximum = 100.0; + double x = amount / amountPerTick * maximum; + component->indirectBufferProgress += x; + if(component->indirectBufferProgress >= maximum) { + component->indirectBufferProgress = 0; + nn_triggerIndirect(component->computer); + } +} diff --git a/src/component.h b/src/component.h index 7ab172a..d78c18c 100644 --- a/src/component.h +++ b/src/component.h @@ -25,6 +25,7 @@ typedef struct nn_componentTable { typedef struct nn_component { nn_address address; int slot; + float indirectBufferProgress; nn_componentTable *table; void *statePtr; nn_computer *computer; diff --git a/src/computer.c b/src/computer.c index 75c5753..f80aabb 100644 --- a/src/computer.c +++ b/src/computer.c @@ -219,24 +219,29 @@ bool nn_isUser(nn_computer *computer, const char *name) { return false; } -void nn_setCallBudget(nn_computer *computer, size_t callBudget) { +void nn_setCallBudget(nn_computer *computer, double callBudget) { computer->callBudget = callBudget; } -size_t nn_getCallBudget(nn_computer *computer) { +double nn_getCallBudget(nn_computer *computer) { return computer->callBudget; } -void nn_callCost(nn_computer *computer, size_t cost) { +void nn_callCost(nn_computer *computer, double cost) { computer->callCost += cost; + if(computer->callCost >= computer->callBudget) nn_triggerIndirect(computer); } -size_t nn_getCallCost(nn_computer *computer) { +double nn_getCallCost(nn_computer *computer) { return computer->callCost; } bool nn_isOverworked(nn_computer *computer) { - return computer->callCost >= computer->callBudget; + return computer->state == NN_STATE_OVERWORKED; +} + +void nn_triggerIndirect(nn_computer *computer) { + computer->state = NN_STATE_OVERWORKED; } int nn_getState(nn_computer *computer) { diff --git a/src/computer.h b/src/computer.h index db3307b..6718cd0 100644 --- a/src/computer.h +++ b/src/computer.h @@ -40,8 +40,8 @@ typedef struct nn_computer { double temperature; double temperatureCoefficient; double roomTemperature; - size_t callCost; - size_t callBudget; + double callCost; + double callBudget; } nn_computer; #endif diff --git a/src/emulator.c b/src/emulator.c index abe2f7b..c2da9fa 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -712,9 +712,6 @@ int main() { } int state = nn_tickComputer(computer); - if(nn_isOverworked(computer)) { - printf("Machine overworked.\n"); - } if(state == NN_STATE_SWITCH) { nn_architecture *nextArch = nn_getNextArchitecture(computer); printf("Next architecture: %s\n", nextArch->archName); diff --git a/src/neonucleus.h b/src/neonucleus.h index b582b66..5e33ce4 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -69,7 +69,6 @@ extern "C" { #define NN_CALL_HEAT 0.05 #define NN_CALL_COST 1 #define NN_LABEL_SIZE 128 -#define NN_INDIRECT_CALL_LATENCY 0.0005 typedef struct nn_guard nn_guard; typedef atomic_size_t nn_refc; @@ -235,11 +234,12 @@ const char *nn_addUser(nn_computer *computer, const char *name); void nn_deleteUser(nn_computer *computer, const char *name); const char *nn_indexUser(nn_computer *computer, size_t idx); bool nn_isUser(nn_computer *computer, const char *name); -void nn_setCallBudget(nn_computer *computer, size_t callBudget); -size_t nn_getCallBudget(nn_computer *computer); -void nn_callCost(nn_computer *computer, size_t cost); -size_t nn_getCallCost(nn_computer *computer); +void nn_setCallBudget(nn_computer *computer, double callBudget); +double nn_getCallBudget(nn_computer *computer); +void nn_callCost(nn_computer *computer, double cost); +double nn_getCallCost(nn_computer *computer); bool nn_isOverworked(nn_computer *computer); +void nn_triggerIndirect(nn_computer *computer); /* The memory returned can be freed with nn_free() */ char *nn_serializeProgram(nn_computer *computer, size_t *len); @@ -277,6 +277,9 @@ void nn_unlockComputer(nn_computer *computer); /// The architecture is returned by getNextArchitecture. #define NN_STATE_SWITCH 6 +/// The machine is overworked. +#define NN_STATE_OVERWORKED 7 + int nn_getState(nn_computer *computer); void nn_setState(nn_computer *computer, int state); @@ -346,6 +349,7 @@ const char *nn_methodDoc(nn_componentTable *table, const char *methodName); /* Returns false if the method does not exist */ bool nn_invokeComponentMethod(nn_component *component, const char *name); +void nn_simulateBufferedIndirect(nn_component *component, double amount, double amountPerTick); void nn_resetCall(nn_computer *computer); void nn_addArgument(nn_computer *computer, nn_value arg); void nn_return(nn_computer *computer, nn_value val);