mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2026-02-15 04:03:49 +01:00
better signal semantics and windows mutexes
This commit is contained in:
parent
4a2a60990b
commit
3f39ac27a0
@ -60,7 +60,7 @@ typedef struct nn_Lock nn_Lock;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NN_WINDOWS
|
#ifdef NN_WINDOWS
|
||||||
#include <Windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -348,7 +348,19 @@ static void nn_defaultLock(void *state, nn_LockRequest *req) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#elif defined(NN_THREAD_WINDOWS)
|
#elif defined(NN_THREAD_WINDOWS)
|
||||||
#error "Windows locks are not supported yet"
|
switch(req->action) {
|
||||||
|
case NN_LOCK_CREATE:;
|
||||||
|
req->lock = CreateMutex(NULL, false, NULL);
|
||||||
|
case NN_LOCK_DESTROY:;
|
||||||
|
CloseHandle(req->lock);
|
||||||
|
return;
|
||||||
|
case NN_LOCK_LOCK:;
|
||||||
|
WaitForSingleObject(req->lock, INFINITE);
|
||||||
|
return;
|
||||||
|
case NN_LOCK_UNLOCK:;
|
||||||
|
ReleaseMutex(req->lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -1249,6 +1261,41 @@ int nn_countValueCost(nn_Computer *computer, size_t values) {
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t nn_countSignalCostValue(nn_Value value) {
|
||||||
|
size_t total = 2;
|
||||||
|
switch(value.type) {
|
||||||
|
case NN_VAL_NULL:
|
||||||
|
case NN_VAL_BOOL:
|
||||||
|
total += 4;
|
||||||
|
break;
|
||||||
|
case NN_VAL_NUM:
|
||||||
|
case NN_VAL_USERDATA:
|
||||||
|
total += 8;
|
||||||
|
break;
|
||||||
|
case NN_VAL_STR:
|
||||||
|
// 2+1
|
||||||
|
if(value.string->len == 0) total++;
|
||||||
|
else total += value.string->len;
|
||||||
|
break;
|
||||||
|
case NN_VAL_TABLE:
|
||||||
|
total += 2;
|
||||||
|
for(size_t i = 0; i < value.table->len * 2; i++) {
|
||||||
|
total += nn_countSignalCostValue(value.table->vals[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t nn_countSignalCost(nn_Computer *computer, size_t values) {
|
||||||
|
size_t total = 0;
|
||||||
|
for(size_t i = 0; i < values; i++) {
|
||||||
|
nn_Value val = computer->callstack[computer->stackSize - values + i];
|
||||||
|
total += nn_countSignalCostValue(val);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
size_t nn_countSignals(nn_Computer *computer) {
|
size_t nn_countSignals(nn_Computer *computer) {
|
||||||
return computer->signalCount;
|
return computer->signalCount;
|
||||||
}
|
}
|
||||||
@ -1258,7 +1305,7 @@ nn_Exit nn_pushSignal(nn_Computer *computer, size_t valueCount) {
|
|||||||
if(computer->signalCount == NN_MAX_SIGNALS) return NN_ELIMIT;
|
if(computer->signalCount == NN_MAX_SIGNALS) return NN_ELIMIT;
|
||||||
if(computer->stackSize < valueCount) return NN_EBELOWSTACK;
|
if(computer->stackSize < valueCount) return NN_EBELOWSTACK;
|
||||||
|
|
||||||
int cost = nn_countValueCost(computer, valueCount);
|
int cost = nn_countSignalCost(computer, valueCount);
|
||||||
if(cost == -1) return NN_EBADSTATE;
|
if(cost == -1) return NN_EBADSTATE;
|
||||||
if(cost > NN_MAX_SIGNALSIZE) return NN_ELIMIT;
|
if(cost > NN_MAX_SIGNALSIZE) return NN_ELIMIT;
|
||||||
|
|
||||||
|
|||||||
@ -459,8 +459,22 @@ nn_Exit nn_dumptable(nn_Computer *computer, size_t idx, size_t *len);
|
|||||||
// computes the cost of the top [values] values using the same algorithm as
|
// computes the cost of the top [values] values using the same algorithm as
|
||||||
// the modem.
|
// the modem.
|
||||||
// It will return -1 if the values are invalid.
|
// It will return -1 if the values are invalid.
|
||||||
|
// The algorithm is as mentioned in https://ocdoc.cil.li/component:modem
|
||||||
|
// and is as follows:
|
||||||
|
// - Every value adds a 2 byte overhead
|
||||||
|
// - Numbers add another 8 bytes, true/false/null another 4 bytes, strings as
|
||||||
|
// many bytes as they contain, except empty strings count as 1 byte.
|
||||||
int nn_countValueCost(nn_Computer *computer, size_t values);
|
int nn_countValueCost(nn_Computer *computer, size_t values);
|
||||||
|
|
||||||
|
// computes the signal cost.
|
||||||
|
// This is a slightly modified version of value cost, except it allows
|
||||||
|
// tables and userdata.
|
||||||
|
// All values are always valid.
|
||||||
|
// For userdata and tables:
|
||||||
|
// - Userdata adds another 8 bytes overhead like numbers do.
|
||||||
|
// - Tables add yet another 2 byte overhead for their terminator, and the sum of all of the size of the keys and values they contain as per this algorithm.
|
||||||
|
size_t nn_countSignalCost(nn_Computer *computer, size_t values);
|
||||||
|
|
||||||
// Returns the amount of signals stored
|
// Returns the amount of signals stored
|
||||||
size_t nn_countSignals(nn_Computer *computer);
|
size_t nn_countSignals(nn_Computer *computer);
|
||||||
// Pops [valueCount] values from the call stack and pushes them as a signal.
|
// Pops [valueCount] values from the call stack and pushes them as a signal.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user