chore(stdlib): update xod/mutex

This commit is contained in:
Kirill Shumilov
2020-08-19 18:42:30 +03:00
committed by Evgeny Kochetkov
parent 4bc52d5e13
commit f6590fba52
4 changed files with 109 additions and 114 deletions

View File

@@ -1,21 +1,19 @@
#pragma XOD evaluate_on_pin disable
#pragma XOD evaluate_on_pin enable input_DO
struct State {
};
{{ GENERATED_CODE }}
node {
void evaluate(Context ctx) {
auto mux = getValue<input_MUX>(ctx);
void evaluate(Context ctx) {
auto mux = getValue<input_MUX>(ctx);
if (isSettingUp()) {
// Short-circuit RES and RES'
emitValue<output_MUXU0027>(ctx, mux);
}
if (isSettingUp()) {
// Short-circuit RES and RES'
emitValue<output_MUXU0027>(ctx, mux);
if (!isInputDirty<input_DO>(ctx))
return;
mux->forceUnlock();
emitValue<output_DONE>(ctx, 1);
}
if (!isInputDirty<input_DO>(ctx))
return;
mux->forceUnlock();
emitValue<output_DONE>(ctx, 1);
}

View File

@@ -1,32 +1,28 @@
node {
void evaluate(Context ctx) {
auto mux = getValue<input_MUX>(ctx);
struct State {
};
if (isSettingUp()) {
// Short-circuit RES and RES'
emitValue<output_MUXU0027>(ctx, mux);
}
{{ GENERATED_CODE }}
bool justEntered = false;
auto nodeId = getNodeId(ctx);
void evaluate(Context ctx) {
auto mux = getValue<input_MUX>(ctx);
if (isInputDirty<input_ACQ>(ctx) && mux->lockFor(nodeId)) {
justEntered = true;
}
if (isSettingUp()) {
// Short-circuit RES and RES'
emitValue<output_MUXU0027>(ctx, mux);
if (isInputDirty<input_RLS>(ctx) && mux->unlock(nodeId)) {
justEntered = false;
emitValue<output_RLSd>(ctx, 1);
}
if (justEntered)
emitValue<output_ACQd>(ctx, 1);
if (isInputDirty<input_IN>(ctx) && mux->isLockedFor(nodeId))
emitValue<output_OUT>(ctx, 1);
}
bool justEntered = false;
auto nodeId = getNodeId(ctx);
if (isInputDirty<input_ACQ>(ctx) && mux->lockFor(nodeId)) {
justEntered = true;
}
if (isInputDirty<input_RLS>(ctx) && mux->unlock(nodeId)) {
justEntered = false;
emitValue<output_RLSd>(ctx, 1);
}
if (justEntered)
emitValue<output_ACQd>(ctx, 1);
if (isInputDirty<input_IN>(ctx) && mux->isLockedFor(nodeId))
emitValue<output_OUT>(ctx, 1);
}

View File

@@ -1,37 +1,33 @@
node {
void evaluate(Context ctx) {
auto mux = getValue<input_MUX>(ctx);
struct State {
};
if (isSettingUp()) {
// Short-circuit RES and RES'
emitValue<output_MUXU0027>(ctx, mux);
}
{{ GENERATED_CODE }}
bool justEntered = false;
auto nodeId = getNodeId(ctx);
void evaluate(Context ctx) {
auto mux = getValue<input_MUX>(ctx);
if (isInputDirty<input_ACQ>(ctx) && mux->lockFor(nodeId)) {
justEntered = true;
}
if (isSettingUp()) {
// Short-circuit RES and RES'
emitValue<output_MUXU0027>(ctx, mux);
}
if (isInputDirty<input_RLS>(ctx) && mux->unlock(nodeId)) {
justEntered = false;
emitValue<output_RLSd>(ctx, 1);
}
bool justEntered = false;
auto nodeId = getNodeId(ctx);
if (justEntered)
emitValue<output_ACQd>(ctx, 1);
if (isInputDirty<input_ACQ>(ctx) && mux->lockFor(nodeId)) {
justEntered = true;
}
auto active = mux->isLockedFor(nodeId);
emitValue<output_ACT>(ctx, active);
if (isInputDirty<input_RLS>(ctx) && mux->unlock(nodeId)) {
justEntered = false;
emitValue<output_RLSd>(ctx, 1);
}
if (justEntered)
emitValue<output_ACQd>(ctx, 1);
auto active = mux->isLockedFor(nodeId);
emitValue<output_ACT>(ctx, active);
if (active) {
emitValue<output_LOOP>(ctx, 1);
setTimeout(ctx, 0);
if (active) {
emitValue<output_LOOP>(ctx, 1);
setTimeout(ctx, 0);
}
}
}

View File

@@ -1,56 +1,61 @@
namespace xod {
namespace mutex {
using NodeId = uint16_t;
/*
Represents some resource that should be owned/controlled exclusively by a node
to perform a non-instant task.
using NodeId = uint16_t;
An example is a node which slowly rotates a motor shaft. The process is long
(several seconds) and a particular rotation node can lock the motor resource
so that other sibling rotation nodes cant cause a conflict until the job is
done and the motor resource is unlocked.
*/
class Mutex {
public:
static constexpr NodeId NO_LOCK = 0xFFFF;
/*
Represents some resource that should be owned/controlled exclusively by a node
to perform a non-instant task.
bool lockFor(NodeId nodeId) {
if (isLocked())
return false;
An example is a node which slowly rotates a motor shaft. The process is long
(several seconds) and a particular rotation node can lock the motor resource
so that other sibling rotation nodes cant cause a conflict until the job is
done and the motor resource is unlocked.
*/
class Mutex {
public:
static constexpr NodeId NO_LOCK = 0xFFFF;
_lockedFor = nodeId;
return true;
}
bool lockFor(NodeId nodeId) {
if (isLocked())
return false;
bool unlock(NodeId nodeId) {
if (!isLockedFor(nodeId))
return false;
_lockedFor = nodeId;
return true;
forceUnlock();
return true;
}
void forceUnlock() {
_lockedFor = NO_LOCK;
}
bool isLocked() const {
return _lockedFor != NO_LOCK;
}
bool isLockedFor(NodeId nodeId) const {
return _lockedFor == nodeId;
}
protected:
NodeId _lockedFor = NO_LOCK;
};
} // namespace mutex
} // namespace xod
node {
meta {
using Type = xod::mutex::Mutex*;
}
bool unlock(NodeId nodeId) {
if (!isLockedFor(nodeId))
return false;
xod::mutex::Mutex mux;
forceUnlock();
return true;
void evaluate(Context ctx) {
emitValue<output_OUT>(ctx, &mux);
}
void forceUnlock() {
_lockedFor = NO_LOCK;
}
bool isLocked() const {
return _lockedFor != NO_LOCK;
}
bool isLockedFor(NodeId nodeId) const {
return _lockedFor == nodeId;
}
protected:
NodeId _lockedFor = NO_LOCK;
};
using State = Mutex;
using Type = Mutex*;
{{ GENERATED_CODE }}
void evaluate(Context ctx) {
emitValue<output_OUT>(ctx, getState(ctx));
}