aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pmem.c73
-rw-r--r--src/uapi/conf.c22
2 files changed, 76 insertions, 19 deletions
diff --git a/src/pmem.c b/src/pmem.c
index 91aff5a..cf70c3f 100644
--- a/src/pmem.c
+++ b/src/pmem.c
@@ -208,11 +208,21 @@ static void __get_bit(struct mm_bucket *bucket, pm_t a, size_t *s, size_t *b)
*b = p % bucket->bits;
}
-void free_page(enum mm_order order, pm_t addr)
+/** Counter for how many bytes are currently in use. */
+static size_t used = 0;
+
+/**
+ * Non-usage counting worker for \ref free_page().
+ *
+ * @param order Order of page to free.
+ * @param addr Address of page to free.
+ * @return \ref true if usage count should be updated, \ref false otherwise.
+ */
+static bool __free_page(enum mm_order order, pm_t addr)
{
struct mm_bucket *bucket = pmap->buckets[order];
if (!bucket)
- return;
+ return false;
size_t set = 0, bit = 0;
__get_bit(bucket, addr, &set, &bit);
@@ -227,11 +237,25 @@ void free_page(enum mm_order order, pm_t addr)
__detach_set(bucket, bmap);
if (bmap->size == order_width(order + 1))
- free_page(order + 1, __page_addr(bucket, set, bit));
+ __free_page(order + 1, __page_addr(bucket, set, bit));
}
+
+ return true;
}
-pm_t alloc_page(enum mm_order order)
+void free_page(enum mm_order order, pm_t addr)
+{
+ if (__free_page(order, addr))
+ used -= order_size(order);
+}
+
+/**
+ * Non-usage counting worker for \ref alloc_page().
+ *
+ * @param order Order of page to allocate.
+ * @return Address of allocated page, NULL of no page available.
+ */
+static pm_t __alloc_page(enum mm_order order)
{
struct mm_bucket *bucket = pmap->buckets[order];
if (!bucket)
@@ -239,7 +263,7 @@ pm_t alloc_page(enum mm_order order)
struct mm_bmap *bmap = bucket->head;
if (!bmap) {
- pm_t a = alloc_page(order + 1);
+ pm_t a = __alloc_page(order + 1);
if (!a)
return 0;
@@ -250,7 +274,7 @@ pm_t alloc_page(enum mm_order order)
bmap->used = 0;
bitmap_clear_all(bmap->bits, bmap->size);
__attach_set(bucket, bmap);
- return alloc_page(order);
+ return __alloc_page(order);
}
bmap->used++;
@@ -265,11 +289,27 @@ pm_t alloc_page(enum mm_order order)
return __page_addr(bucket, set, bit);
}
-void mark_used(enum mm_order order, pm_t addr)
+pm_t alloc_page(enum mm_order order)
+{
+ pm_t page = __alloc_page(order);
+ if (page)
+ used += order_size(order);
+
+ return page;
+}
+
+/**
+ * Non-usage counting worker for \ref __mark_used().
+ *
+ * @param order Order of page to mark used.
+ * @param addr Address of page to mark used.
+ * @return \ref true if usage count should be updated, \ref false otherwise.
+ */
+static bool __mark_used(enum mm_order order, pm_t addr)
{
struct mm_bucket *bucket = pmap->buckets[order];
if (!bucket)
- return;
+ return false;
size_t set = 0, bit = 0;
__get_bit(bucket, addr, &set, &bit);
@@ -278,7 +318,7 @@ void mark_used(enum mm_order order, pm_t addr)
if (bmap->used == 0) {
bitmap_clear_all(bmap->bits, bmap->size);
__attach_set(bucket, bmap);
- mark_used(order + 1, addr);
+ __mark_used(order + 1, addr);
}
/* a page already in use can just be left alone. This MIGHT hide some
@@ -286,13 +326,26 @@ void mark_used(enum mm_order order, pm_t addr)
* initialization, but that scenario should probably be handled outside
* of this function anyway. */
if (bitmap_is_set(bmap->bits, bit))
- return;
+ return false;
bmap->used++;
bitmap_set(bmap->bits, bit);
if (bmap->used == bmap->size)
__detach_set(bucket, bmap);
+
+ return true;
+}
+
+void mark_used(enum mm_order order, pm_t addr)
+{
+ if (__mark_used(order, addr))
+ used += order_size(order);
+}
+
+size_t query_used()
+{
+ return used;
}
/**
diff --git a/src/uapi/conf.c b/src/uapi/conf.c
index 685d294..be9abfc 100644
--- a/src/uapi/conf.c
+++ b/src/uapi/conf.c
@@ -21,12 +21,6 @@
size_t __thread_stack_size = SZ_2M;
size_t __rpc_stack_size = SZ_512K;
-/** IDs for configuration parameters. */
-/** @todo should probably be moved somewhere so it can be shared with userspace */
-enum conf_param {
- CONF_THREAD_STACK = 0,
- CONF_RPC_STACK,
-};
/**
* Configuration parameter read syscall handler.
@@ -39,9 +33,8 @@ enum conf_param {
*/
SYSCALL_DEFINE1(conf_get)(struct tcb *t, sys_arg_t param)
{
- if (!has_cap(t->caps, CAP_CONF))
- return_args1(t, ERR_PERM);
-
+ /* anyone can read any current parameter, I don't think they should be
+ * hidden. */
long val = 0;
switch (param) {
case CONF_THREAD_STACK:
@@ -52,6 +45,14 @@ SYSCALL_DEFINE1(conf_get)(struct tcb *t, sys_arg_t param)
val = __rpc_stack_size;
break;
+ case CONF_RAM_USAGE:
+ val = query_used();
+ break;
+
+ case CONF_RAM_SIZE:
+ val = get_ram_size();
+ break;
+
default:
return_args1(t, ERR_NF);
}
@@ -87,6 +88,9 @@ SYSCALL_DEFINE2(conf_set)(struct tcb *t, sys_arg_t param, sys_arg_t val)
__rpc_stack_size = size;
break;
+
+ default:
+ return_args1(t, ERR_INVAL);
}
return_args1(t, OK);