1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#define _POSIX_C_SOURCE 200809L
/* Linux-only whole-app evidence: many independent native app instances, each
* exercising the execution core, scalar program and durable state path. */
#include "app.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
extern const PureScalarPlan pure_app_plan;
static long rss_kib(void) {
FILE *file = fopen("/proc/self/status", "r");
if (!file) return -1;
char line[256];
long result = -1;
while (fgets(line, sizeof(line), file))
if (strncmp(line, "VmRSS:", 6) == 0) {
if (sscanf(line + 6, "%ld", &result) != 1) result = -1;
break;
}
fclose(file);
return result;
}
int main(void) {
enum { COUNT = 1000 };
char directory[] = "/tmp/pure-app-memory-XXXXXX";
assert(mkdtemp(directory));
long before = rss_kib();
assert(before >= 0);
PureNativeApp *apps = calloc(COUNT, sizeof(*apps));
void **scalar_memory = calloc(COUNT, sizeof(*scalar_memory));
assert(apps && scalar_memory);
size_t scalar_bytes = pure_scalar_bytes();
size_t completed_actions = 0, completed_transfers = 0;
for (size_t i = 0; i < COUNT; ++i) {
scalar_memory[i] = malloc(scalar_bytes);
assert(scalar_memory[i]);
char key[32];
snprintf(key, sizeof(key), "doc%04zu", i);
assert(pure_native_app_init(&apps[i], &pure_app_plan, scalar_memory[i],
scalar_bytes, directory, key, 4096) == PURE_OK);
assert(pure_native_app_action(&apps[i], (PureAction){.phase = PURE_RESET}).status == PURE_OK);
++completed_actions;
#ifndef PURE_APP_MEMORY_PERSISTENT_WORK
assert(!apps[i].execution.work && !apps[i].execution.capacity);
#endif
}
long initialized = rss_kib();
assert(initialized >= before);
for (size_t i = 0; i < COUNT; ++i) {
assert(pure_native_app_save(&apps[i]).status == PURE_OK);
++completed_transfers;
assert(apps[i].stored_revision == 1);
assert(!apps[i].execution.active && !apps[i].execution.retained);
#ifndef PURE_APP_MEMORY_PERSISTENT_WORK
assert(!apps[i].execution.work && !apps[i].execution.capacity);
#endif
}
long saved = rss_kib();
assert(saved >= before);
for (size_t i = 0; i < COUNT; i += 249) {
assert(pure_native_app_restore(&apps[i]).status == PURE_OK);
++completed_transfers;
}
for (size_t i = 0; i < COUNT; ++i) {
assert(!apps[i].execution.active && !apps[i].execution.retained);
char name[128];
snprintf(name, sizeof(name), "%s/obj-%s", directory, apps[i].document);
assert(unlink(name) == 0);
free(scalar_memory[i]);
}
char lock[128];
snprintf(lock, sizeof(lock), "%s/.writer.lock", directory);
assert(unlink(lock) == 0 && rmdir(directory) == 0);
printf("{\"apps\":%u,\"app_controller_bytes\":%zu,\"scalar_bytes\":%zu,"
"\"rss_before_kib\":%ld,\"rss_initialized_kib\":%ld,\"rss_saved_kib\":%ld,"
"\"rss_initialized_delta_kib\":%ld,\"rss_saved_delta_kib\":%ld,"
"\"completed_actions\":%zu,\"completed_transfers\":%zu}\n",
COUNT, sizeof(*apps), scalar_bytes, before, initialized, saved,
initialized - before, saved - before, completed_actions, completed_transfers);
free(scalar_memory);
free(apps);
return 0;
}
|