Skip to content

Commit 4492339

Browse files
committed
kv: Support garbage collection from userspace
Signed-off-by: Alistair Francis <[email protected]>
1 parent 8205794 commit 4492339

File tree

8 files changed

+81
-1
lines changed

8 files changed

+81
-1
lines changed

examples/tests/kv/kv_unit_tests/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ TOCK_USERLAND_BASE_DIR = ../../../..
66
# Which files to compile.
77
C_SRCS := $(wildcard *.c)
88

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

1113
# Include userland master makefile. Contains rules and flags for actually
1214
# building the application.

examples/tests/kv/kv_unit_tests/main.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,50 @@ static bool test_set_get_32regions_8(void) {
394394
return subtest_set_get_region(28, 32);
395395
}
396396

397+
static bool test_garbage_collect(void) {
398+
int ret;
399+
char key[] = "kvtestapp";
400+
strcpy((char*) key_buf, key);
401+
int num_of_keys = 0;
402+
uint32_t value_len = 500;
403+
404+
printf("Filling up storage with invalid (deleted) keys\r\n");
405+
406+
// Fill up the storage
407+
do {
408+
for (uint32_t i = 0; i < value_len; i++) {
409+
value_buf[i] = num_of_keys;
410+
}
411+
412+
printf("Setting key %d\r\n", num_of_keys);
413+
ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len);
414+
415+
if (ret == RETURNCODE_SUCCESS) {
416+
num_of_keys++;
417+
}
418+
} while (ret == RETURNCODE_SUCCESS);
419+
420+
printf("Wrote %d K/V entries to flash, running garbage collection\n", num_of_keys);
421+
422+
ret = libtocksync_kv_garbage_collect();
423+
CHECK(ret == RETURNCODE_SUCCESS);
424+
425+
printf("Garbage collection finished, trying to re-set the keys\r\n");
426+
427+
for (int i = 0; i < num_of_keys; i++) {
428+
printf("Setting key %d\r\n", i);
429+
for (uint32_t j = 0; j < value_len; j++) {
430+
value_buf[j] = i;
431+
}
432+
433+
CHECK(libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len) == RETURNCODE_SUCCESS);
434+
}
435+
436+
printf("Set all keys\r\n");
437+
438+
return true;
439+
}
440+
397441
int main(void) {
398442
unit_test_fun tests[] = {
399443
TEST(exists),
@@ -419,6 +463,7 @@ int main(void) {
419463
TEST(set_get_32regions_6),
420464
TEST(set_get_32regions_7),
421465
TEST(set_get_32regions_8),
466+
TEST(garbage_collect),
422467
};
423468
unit_test_runner(tests, sizeof(tests) / sizeof(unit_test_fun), 2000, "org.tockos.unit_test");
424469
return 0;

libtock-sync/storage/kv.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,15 @@ returncode_t libtocksync_kv_delete(const uint8_t* key_buffer, uint32_t key_len)
7878
yield_for(&result.fired);
7979
return result.ret;
8080
}
81+
82+
returncode_t libtocksync_kv_garbage_collect(void) {
83+
returncode_t err;
84+
result.fired = false;
85+
86+
err = libtock_kv_garbage_collect(kv_cb_done);
87+
if (err != RETURNCODE_SUCCESS) return err;
88+
89+
// Wait for the callback.
90+
yield_for(&result.fired);
91+
return result.ret;
92+
}

libtock-sync/storage/kv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ returncode_t libtocksync_kv_update(const uint8_t* key_buffer, uint32_t key_len,
2121

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

24+
returncode_t libtocksync_kv_garbage_collect(void);
25+
2426
#ifdef __cplusplus
2527
}
2628
#endif

libtock/storage/kv.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,13 @@ returncode_t libtock_kv_delete(const uint8_t* key_buffer, uint32_t key_len, libt
8181
err = libtock_kv_command_delete();
8282
return err;
8383
}
84+
85+
returncode_t libtock_kv_garbage_collect(libtock_kv_callback_done cb) {
86+
returncode_t err;
87+
88+
err = libtock_kv_set_upcall(kv_upcall_done, cb);
89+
if (err != RETURNCODE_SUCCESS) return err;
90+
91+
err = libtock_kv_command_garbage_collect();
92+
return err;
93+
}

libtock/storage/kv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ returncode_t libtock_kv_update(const uint8_t* key_buffer, uint32_t key_len, cons
3333

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

36+
returncode_t libtock_kv_garbage_collect(libtock_kv_callback_done cb);
3637

3738
#ifdef __cplusplus
3839
}

libtock/storage/syscalls/kv_syscalls.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#define TOCK_KV_DELETE 3
1212
#define TOCK_KV_ADD 4
1313
#define TOCK_KV_UPDATE 5
14+
#define TOCK_KV_GARBAGE_COLLECT 6
1415

1516
bool libtock_kv_exists(void) {
1617
return driver_exists(DRIVER_NUM_KV);
@@ -51,6 +52,11 @@ returncode_t libtock_kv_command_delete(void) {
5152
return tock_command_return_novalue_to_returncode(cval);
5253
}
5354

55+
returncode_t libtock_kv_command_garbage_collect(void) {
56+
syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_GARBAGE_COLLECT, 0, 0);
57+
return tock_command_return_novalue_to_returncode(cval);
58+
}
59+
5460
returncode_t libtock_kv_command_add(void) {
5561
syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_ADD, 0, 0);
5662
return tock_command_return_novalue_to_returncode(cval);

libtock/storage/syscalls/kv_syscalls.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ returncode_t libtock_kv_command_set(void);
2424

2525
returncode_t libtock_kv_command_delete(void);
2626

27+
returncode_t libtock_kv_command_garbage_collect(void);
28+
2729
returncode_t libtock_kv_command_add(void);
2830

2931
returncode_t libtock_kv_command_update(void);

0 commit comments

Comments
 (0)