mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-24 09:03:32 +02:00
initial work on some interfaces
This commit is contained in:
parent
5d084a51b9
commit
f14474ebb7
@ -1,7 +1,7 @@
|
|||||||
#include "../neonucleus.h"
|
#include "../neonucleus.h"
|
||||||
|
|
||||||
void nn_eeprom_destroy(void *_, nn_component *component, nn_eeprom *eeprom) {
|
void nn_eeprom_destroy(void *_, nn_component *component, nn_eeprom *eeprom) {
|
||||||
if(atomic_fetch_sub(&eeprom->refc, 1) > 1) return;
|
if(!nn_decRef(&eeprom->refc)) return;
|
||||||
|
|
||||||
if(eeprom->deinit == NULL) {
|
if(eeprom->deinit == NULL) {
|
||||||
eeprom->deinit(component, eeprom);
|
eeprom->deinit(component, eeprom);
|
||||||
@ -56,7 +56,8 @@ void nn_eeprom_set(nn_eeprom *eeprom, void *_, nn_component *component, nn_compu
|
|||||||
size_t len;
|
size_t len;
|
||||||
const char *buf = nn_toString(data, &len);
|
const char *buf = nn_toString(data, &len);
|
||||||
if(len > eeprom->getSize(component, eeprom->userdata)) {
|
if(len > eeprom->getSize(component, eeprom->userdata)) {
|
||||||
|
nn_setCError(computer, "out of space");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
eeprom->set(component, eeprom->userdata, buf, len);
|
eeprom->set(component, eeprom->userdata, buf, len);
|
||||||
}
|
}
|
||||||
@ -81,6 +82,10 @@ void nn_eeprom_setData(nn_eeprom *eeprom, void *_, nn_component *component, nn_c
|
|||||||
nn_value data = nn_getArgument(computer, 0);
|
nn_value data = nn_getArgument(computer, 0);
|
||||||
size_t len;
|
size_t len;
|
||||||
const char *buf = nn_toString(data, &len);
|
const char *buf = nn_toString(data, &len);
|
||||||
|
if(len > eeprom->getDataSize(component, eeprom->userdata)) {
|
||||||
|
nn_setCError(computer, "out of space");
|
||||||
|
return;
|
||||||
|
}
|
||||||
eeprom->setData(component, eeprom->userdata, buf, len);
|
eeprom->setData(component, eeprom->userdata, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
src/lock.c
17
src/lock.c
@ -26,3 +26,20 @@ void nn_deleteGuard(nn_guard *guard) {
|
|||||||
if(guard == NULL) return;
|
if(guard == NULL) return;
|
||||||
mtx_destroy(&guard->m);
|
mtx_destroy(&guard->m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nn_addRef(nn_refc *refc, size_t count) {
|
||||||
|
atomic_fetch_add(refc, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_incRef(nn_refc *refc) {
|
||||||
|
nn_addRef(refc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nn_removeRef(nn_refc *refc, size_t count) {
|
||||||
|
size_t old = atomic_fetch_sub(refc, count);
|
||||||
|
return old == count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nn_decRef(nn_refc *refc) {
|
||||||
|
return nn_removeRef(refc, 1);
|
||||||
|
}
|
||||||
|
@ -58,6 +58,8 @@
|
|||||||
#define NN_MAX_USERDATA 1024
|
#define NN_MAX_USERDATA 1024
|
||||||
#define NN_MAX_USER_SIZE 128
|
#define NN_MAX_USER_SIZE 128
|
||||||
#define NN_MAX_SIGNAL_SIZE 8192
|
#define NN_MAX_SIGNAL_SIZE 8192
|
||||||
|
#define NN_MAX_OPEN_FILES 128
|
||||||
|
|
||||||
#define NN_OVERHEAT_MIN 100
|
#define NN_OVERHEAT_MIN 100
|
||||||
#define NN_CALL_HEAT 0.05
|
#define NN_CALL_HEAT 0.05
|
||||||
#define NN_CALL_COST 1
|
#define NN_CALL_COST 1
|
||||||
@ -65,6 +67,7 @@
|
|||||||
#define NN_INDIRECT_CALL_LATENCY 0.05
|
#define NN_INDIRECT_CALL_LATENCY 0.05
|
||||||
|
|
||||||
typedef struct nn_guard nn_guard;
|
typedef struct nn_guard nn_guard;
|
||||||
|
typedef atomic_size_t nn_refc;
|
||||||
typedef struct nn_universe nn_universe;
|
typedef struct nn_universe nn_universe;
|
||||||
typedef struct nn_computer nn_computer;
|
typedef struct nn_computer nn_computer;
|
||||||
typedef struct nn_component nn_component;
|
typedef struct nn_component nn_component;
|
||||||
@ -143,6 +146,13 @@ void nn_lock(nn_guard *guard);
|
|||||||
void nn_unlock(nn_guard *guard);
|
void nn_unlock(nn_guard *guard);
|
||||||
void nn_deleteGuard(nn_guard *guard);
|
void nn_deleteGuard(nn_guard *guard);
|
||||||
|
|
||||||
|
void nn_addRef(nn_refc *refc, size_t count);
|
||||||
|
void nn_incRef(nn_refc *refc);
|
||||||
|
/* Returns true if the object should be freed */
|
||||||
|
bool nn_removeRef(nn_refc *refc, size_t count);
|
||||||
|
/* Returns true if the object should be freed */
|
||||||
|
bool nn_decRef(nn_refc *refc);
|
||||||
|
|
||||||
double nn_realTime();
|
double nn_realTime();
|
||||||
double nn_realTimeClock(void *_);
|
double nn_realTimeClock(void *_);
|
||||||
/* Will busy-loop until the time passes. This is meant for computed latencies in components. */
|
/* Will busy-loop until the time passes. This is meant for computed latencies in components. */
|
||||||
@ -334,13 +344,14 @@ void nn_loadCoreComponentTables(nn_universe *universe);
|
|||||||
|
|
||||||
// loading each component
|
// loading each component
|
||||||
void nn_loadEepromTable(nn_universe *universe);
|
void nn_loadEepromTable(nn_universe *universe);
|
||||||
|
void nn_loadFilesystemTable(nn_universe *universe);
|
||||||
|
|
||||||
// the helpers
|
// the helpers
|
||||||
|
|
||||||
// EEPROM
|
// EEPROM
|
||||||
typedef struct nn_eeprom {
|
typedef struct nn_eeprom {
|
||||||
|
nn_refc refc;
|
||||||
void *userdata;
|
void *userdata;
|
||||||
atomic_size_t refc;
|
|
||||||
void (*deinit)(nn_component *component, void *userdata);
|
void (*deinit)(nn_component *component, void *userdata);
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -357,4 +368,82 @@ typedef struct nn_eeprom {
|
|||||||
} nn_eeprom;
|
} nn_eeprom;
|
||||||
nn_component *nn_addEeprom(nn_computer *computer, nn_address address, int slot, nn_eeprom *eeprom);
|
nn_component *nn_addEeprom(nn_computer *computer, nn_address address, int slot, nn_eeprom *eeprom);
|
||||||
|
|
||||||
|
// FileSystem
|
||||||
|
typedef struct nn_filesystemControl {
|
||||||
|
int pretendChunkSize;
|
||||||
|
|
||||||
|
// speed
|
||||||
|
// used to calculate the latency of seeking a file. It will treat the file as continuous within the storage medium, which is completely
|
||||||
|
// unrealistic. Essentially, after a seek, it will check how much the file pointer was changed. If it went backwards, it will pretend
|
||||||
|
// the whole drive had to spin. You can imagine the drive spinning counter-clockwise.
|
||||||
|
// Seeks are assumed to be *chunked* too, so seeking within a chunk, even backwards, won't actually do anything.
|
||||||
|
// Set it to 0 to disable seek latency.
|
||||||
|
int pretendRPM;
|
||||||
|
double readLatencyPerChunk;
|
||||||
|
double writeLatencyPerChunk;
|
||||||
|
|
||||||
|
// these control *random* latencies that each operation will do
|
||||||
|
double randomLatencyMin;
|
||||||
|
double randomLatencyMax;
|
||||||
|
|
||||||
|
// thermals
|
||||||
|
double motorHeat; // this times how many chunks have been seeked will be the heat addres, +/- the heat range.
|
||||||
|
double heatRange;
|
||||||
|
} nn_filesystemControl;
|
||||||
|
|
||||||
|
typedef struct nn_filesystem {
|
||||||
|
nn_refc refc;
|
||||||
|
nn_filesystemControl *control;
|
||||||
|
void *userdata;
|
||||||
|
void (*deinit)(nn_component *component, void *userdata);
|
||||||
|
|
||||||
|
void (*getLabel)(nn_component *component, void *userdata, char *buf, size_t *buflen);
|
||||||
|
size_t (*setLabel)(nn_component *component, void *userdata, const char *buf, size_t buflen);
|
||||||
|
|
||||||
|
size_t (*spaceUsed)(nn_component *component, void *userdata);
|
||||||
|
size_t (*spaceTotal)(nn_component *component, void *userdata);
|
||||||
|
} nn_filesystem;
|
||||||
|
|
||||||
|
nn_filesystem *nn_volatileFileSystem(size_t capacity, nn_filesystemControl *control);
|
||||||
|
nn_component *nn_addFileSystem(nn_computer *computer, nn_address address, int slot, nn_filesystem *filesystem);
|
||||||
|
|
||||||
|
// Drive
|
||||||
|
typedef struct nn_driveControl {
|
||||||
|
// Set it to 0 to disable seek latency.
|
||||||
|
int rpm;
|
||||||
|
|
||||||
|
double readLatencyPerByte;
|
||||||
|
double writeLatencyPerByte;
|
||||||
|
|
||||||
|
double randomLatencyMin;
|
||||||
|
double randomLatencyMax;
|
||||||
|
|
||||||
|
double motorHeat;
|
||||||
|
double heatRange;
|
||||||
|
} nn_driveControl;
|
||||||
|
|
||||||
|
typedef struct nn_drive {
|
||||||
|
nn_refc refc;
|
||||||
|
nn_driveControl *control;
|
||||||
|
void *userdata;
|
||||||
|
void (*deinit)(nn_component *component, void *userdata);
|
||||||
|
|
||||||
|
void (*getLabel)(nn_component *component, void *userdata, char *buf, size_t *buflen);
|
||||||
|
size_t (*setLabel)(nn_component *component, void *userdata, const char *buf, size_t buflen);
|
||||||
|
|
||||||
|
size_t (*getPlatterCount)(nn_component *component, void *userdata);
|
||||||
|
size_t (*getCapacity)(nn_component *component, void *userdata);
|
||||||
|
size_t (*getSectorSize)(nn_component *component, void *userdata);
|
||||||
|
|
||||||
|
// sectors start at 1 as per OC.
|
||||||
|
void (*readSector)(nn_component *component, void *userdata, int sector, char *buf);
|
||||||
|
void (*writeSector)(nn_component *component, void *userdata, int sector, const char *buf);
|
||||||
|
|
||||||
|
// readByte and writeByte will internally use readSector and writeSector. This is to ensure they are handled *consistently.*
|
||||||
|
// Also makes the interface less redundant
|
||||||
|
} nn_drive;
|
||||||
|
|
||||||
|
nn_drive *nn_volatileDrive(size_t capacity, size_t platterCount, nn_driveControl *control);
|
||||||
|
nn_component *nn_addDrive(nn_computer *computer, nn_address address, int slot, nn_drive *drive);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -128,8 +128,10 @@ libcomponent = {
|
|||||||
assert(ok, "blackout")
|
assert(ok, "blackout")
|
||||||
end
|
end
|
||||||
|
|
||||||
if computer.getState() ~= states.busy then
|
if computer.getState() == states.busy then
|
||||||
-- busy gets to try again
|
-- busy gets to try again
|
||||||
|
computer.setState(states.running)
|
||||||
|
else
|
||||||
if r[1] then
|
if r[1] then
|
||||||
return table.unpack(r, 2)
|
return table.unpack(r, 2)
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user