Compare commits
4 Commits
319779a16c
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cdd88a52d | ||
|
|
eca0ac6fe4 | ||
|
|
3d8b09167b | ||
|
|
3edff81d89 |
24
README.md
24
README.md
@@ -17,9 +17,33 @@ Impotent is still work-in-progress:
|
|||||||
5. Most operators are still missing
|
5. Most operators are still missing
|
||||||
6. The user API is completely different from that of PoC Lua
|
6. The user API is completely different from that of PoC Lua
|
||||||
7. Being lock-free, tables are not split to "array" and "hash" parts
|
7. Being lock-free, tables are not split to "array" and "hash" parts
|
||||||
|
8. Userdata is not yet supported.
|
||||||
|
|
||||||
Impotent requires C11 and an architecture with 8-byte atomic operations, but otherwise it is completely cross-platform.
|
Impotent requires C11 and an architecture with 8-byte atomic operations, but otherwise it is completely cross-platform.
|
||||||
|
|
||||||
Performance-wise, it's surprisingly competitive with PoC Lua, considering how quickly it was made up to the point of writing this README (~2 weeks). By far the worst bottleneck is the GC, since it requires all threads and their heaps to synchronize.
|
Performance-wise, it's surprisingly competitive with PoC Lua, considering how quickly it was made up to the point of writing this README (~2 weeks). By far the worst bottleneck is the GC, since it requires all threads and their heaps to synchronize.
|
||||||
|
|
||||||
Certain Lua idioms become impossible under Impotent. For example the idiom of appending to tables (`t[#t + 1] = x`) isn't atomic, therefore `table.insert` should be used instead.
|
Certain Lua idioms become impossible under Impotent. For example the idiom of appending to tables (`t[#t + 1] = x`) isn't atomic, therefore `table.insert` should be used instead.
|
||||||
|
|
||||||
|
## Additions
|
||||||
|
|
||||||
|
Obviously, threading. Any thread can access any value from any other thread, including for reading or writing. Operations such as getting or setting are lock-free in the best case scenario, but other operations (such as the `#` operator) must lock the table temporarily.
|
||||||
|
|
||||||
|
Besides this, I have no intent to greatly deviate from standard Lua, to keep source-level compatibility as best I can. The only addition to the standard library is the `threads` global, with two methods as of now.
|
||||||
|
|
||||||
|
### `threads.run`
|
||||||
|
|
||||||
|
Runs a function in a newly created thread. Does not block the caller.
|
||||||
|
|
||||||
|
threads.run(function()
|
||||||
|
-- Do something expensive
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
### `threads.parallel`
|
||||||
|
|
||||||
|
Runs a function in n parallel threads. Blocks the caller until all threads finish.
|
||||||
|
|
||||||
|
threads.parallel(8, function()
|
||||||
|
-- Do something parallelizable.
|
||||||
|
end)
|
||||||
|
|||||||
5
main.c
5
main.c
@@ -32,7 +32,12 @@ static size_t native_print(LVM *lvm, void *ud, size_t argn, set_LValueU *heap, L
|
|||||||
|
|
||||||
static size_t table_insert(LVM *lvm, void *ud, size_t argn, set_LValueU *heap, LRegSet *regset) {
|
static size_t table_insert(LVM *lvm, void *ud, size_t argn, set_LValueU *heap, LRegSet *regset) {
|
||||||
LTable *tbl = (LTable*) (regset->regs[0].u & ~LTAG_MASK);
|
LTable *tbl = (LTable*) (regset->regs[0].u & ~LTAG_MASK);
|
||||||
|
if(argn == 2) {
|
||||||
ltable_insert(tbl, regset->regs[1], 0);
|
ltable_insert(tbl, regset->regs[1], 0);
|
||||||
|
} else if(argn > 2) {
|
||||||
|
size_t idx = lvalue_to_int32(regset->regs[1]);
|
||||||
|
ltable_insert(tbl, regset->regs[2], idx);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
table.h
19
table.h
@@ -241,9 +241,20 @@ static inline size_t ltable_len(LTable *self) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ltable_insert(LTable *self, LValue val, size_t index) {
|
static inline bool ltable_insert(LTable *self, LValue val, size_t index) {
|
||||||
lrwl_write_lock(&self->lock);
|
lrwl_write_lock(&self->lock);
|
||||||
index = ltable_len_nolock(self) + 1;
|
size_t len = ltable_len_nolock(self);
|
||||||
ltable_set_nolock(self, lvalue_from_int32(index), val);
|
if(index == 0) {
|
||||||
lrwl_write_unlock(&self->lock);
|
index = len + 1;
|
||||||
|
}
|
||||||
|
bool success = false;
|
||||||
|
if(index <= len + 1) {
|
||||||
|
for(size_t i = len; i >= index; i--) {
|
||||||
|
ltable_set_nolock(self, lvalue_from_int32(i + 1), ltable_get_nolock(self, lvalue_from_int32(i)));
|
||||||
|
}
|
||||||
|
ltable_set_nolock(self, lvalue_from_int32(index), val);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
lrwl_write_unlock(&self->lock);
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|||||||
17
table_insert.lua
Normal file
17
table_insert.lua
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
t = {}
|
||||||
|
|
||||||
|
for i = 50, 1, -1 do
|
||||||
|
table.insert(t, 1, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 50, 25, -1 do
|
||||||
|
table.insert(t, #t + 1, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 24, 1, -1 do
|
||||||
|
table.insert(t, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, #t do
|
||||||
|
print(t[i])
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user