Skip to content

Commit

Permalink
kv: Support garbage collection from userspace
Browse files Browse the repository at this point in the history
Signed-off-by: Alistair Francis <[email protected]>
  • Loading branch information
alistair23 committed Jan 6, 2025
1 parent 8205794 commit 4492339
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 1 deletion.
4 changes: 3 additions & 1 deletion examples/tests/kv/kv_unit_tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ TOCK_USERLAND_BASE_DIR = ../../../..
# Which files to compile.
C_SRCS := $(wildcard *.c)

ELF2TAB_ARGS += --write_id 17767 --read_ids 17767 --access_ids 17767
# Magic numbers that have to allign with what the kernel gives this
# application as a short ID.
ELF2TAB_ARGS += --write_id 1153320202 --read_ids 1153320202 --access_ids 1153320202

# Include userland master makefile. Contains rules and flags for actually
# building the application.
Expand Down
45 changes: 45 additions & 0 deletions examples/tests/kv/kv_unit_tests/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,50 @@ static bool test_set_get_32regions_8(void) {
return subtest_set_get_region(28, 32);
}

static bool test_garbage_collect(void) {
int ret;
char key[] = "kvtestapp";
strcpy((char*) key_buf, key);
int num_of_keys = 0;
uint32_t value_len = 500;

printf("Filling up storage with invalid (deleted) keys\r\n");

// Fill up the storage
do {
for (uint32_t i = 0; i < value_len; i++) {
value_buf[i] = num_of_keys;
}

printf("Setting key %d\r\n", num_of_keys);
ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len);

if (ret == RETURNCODE_SUCCESS) {
num_of_keys++;
}
} while (ret == RETURNCODE_SUCCESS);

printf("Wrote %d K/V entries to flash, running garbage collection\n", num_of_keys);

ret = libtocksync_kv_garbage_collect();
CHECK(ret == RETURNCODE_SUCCESS);

printf("Garbage collection finished, trying to re-set the keys\r\n");

for (int i = 0; i < num_of_keys; i++) {
printf("Setting key %d\r\n", i);
for (uint32_t j = 0; j < value_len; j++) {
value_buf[j] = i;
}

CHECK(libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len) == RETURNCODE_SUCCESS);
}

printf("Set all keys\r\n");

return true;
}

int main(void) {
unit_test_fun tests[] = {
TEST(exists),
Expand All @@ -419,6 +463,7 @@ int main(void) {
TEST(set_get_32regions_6),
TEST(set_get_32regions_7),
TEST(set_get_32regions_8),
TEST(garbage_collect),
};
unit_test_runner(tests, sizeof(tests) / sizeof(unit_test_fun), 2000, "org.tockos.unit_test");
return 0;
Expand Down
12 changes: 12 additions & 0 deletions libtock-sync/storage/kv.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,15 @@ returncode_t libtocksync_kv_delete(const uint8_t* key_buffer, uint32_t key_len)
yield_for(&result.fired);
return result.ret;
}

returncode_t libtocksync_kv_garbage_collect(void) {
returncode_t err;
result.fired = false;

err = libtock_kv_garbage_collect(kv_cb_done);
if (err != RETURNCODE_SUCCESS) return err;

// Wait for the callback.
yield_for(&result.fired);
return result.ret;
}
2 changes: 2 additions & 0 deletions libtock-sync/storage/kv.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ returncode_t libtocksync_kv_update(const uint8_t* key_buffer, uint32_t key_len,

returncode_t libtocksync_kv_delete(const uint8_t* key_buffer, uint32_t key_len);

returncode_t libtocksync_kv_garbage_collect(void);

#ifdef __cplusplus
}
#endif
10 changes: 10 additions & 0 deletions libtock/storage/kv.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,13 @@ returncode_t libtock_kv_delete(const uint8_t* key_buffer, uint32_t key_len, libt
err = libtock_kv_command_delete();
return err;
}

returncode_t libtock_kv_garbage_collect(libtock_kv_callback_done cb) {
returncode_t err;

err = libtock_kv_set_upcall(kv_upcall_done, cb);
if (err != RETURNCODE_SUCCESS) return err;

err = libtock_kv_command_garbage_collect();
return err;
}
1 change: 1 addition & 0 deletions libtock/storage/kv.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ returncode_t libtock_kv_update(const uint8_t* key_buffer, uint32_t key_len, cons

returncode_t libtock_kv_delete(const uint8_t* key_buffer, uint32_t key_len, libtock_kv_callback_done cb);

returncode_t libtock_kv_garbage_collect(libtock_kv_callback_done cb);

#ifdef __cplusplus
}
Expand Down
6 changes: 6 additions & 0 deletions libtock/storage/syscalls/kv_syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define TOCK_KV_DELETE 3
#define TOCK_KV_ADD 4
#define TOCK_KV_UPDATE 5
#define TOCK_KV_GARBAGE_COLLECT 6

bool libtock_kv_exists(void) {
return driver_exists(DRIVER_NUM_KV);
Expand Down Expand Up @@ -51,6 +52,11 @@ returncode_t libtock_kv_command_delete(void) {
return tock_command_return_novalue_to_returncode(cval);
}

returncode_t libtock_kv_command_garbage_collect(void) {
syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_GARBAGE_COLLECT, 0, 0);
return tock_command_return_novalue_to_returncode(cval);
}

returncode_t libtock_kv_command_add(void) {
syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_ADD, 0, 0);
return tock_command_return_novalue_to_returncode(cval);
Expand Down
2 changes: 2 additions & 0 deletions libtock/storage/syscalls/kv_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ returncode_t libtock_kv_command_set(void);

returncode_t libtock_kv_command_delete(void);

returncode_t libtock_kv_command_garbage_collect(void);

returncode_t libtock_kv_command_add(void);

returncode_t libtock_kv_command_update(void);
Expand Down

0 comments on commit 4492339

Please sign in to comment.