From 108e18ad35fa017bf98cb6841cddacb945e2c927 Mon Sep 17 00:00:00 2001
From: Gareth Rees Example
+
+
+ mps_sac_t sac;
+ mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
+
+ res = mps_sac_create(&sac, pool, 3, classes);
+ if (res != MPS_RES_OK) {
+ printf("Failed to create the allocation cache!");
+ exit(1);
+ }
+
+
+
+
+
+Example
+
+
+ mps_sac_t sac;
+ mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
+
+ res = mps_sac_create(&sac, pool, 3, classes);
+ if (res != MPS_RES_OK) {
+ printf("Failed to create the allocation cache!");
+ exit(1);
+ }
+
+
+
+
+ .. note::
+
+ Some pools will work more efficiently with segregated
+ allocation caches than others. [WHICH?] In the future, the MPS might
+ offer pools specially optimized for particular types of cache. [WHEN?]
+
+
+ Segregated allocation caches work poorly with debugging pool
+ classes: the debugging checks only happen when blocks are
+ moved between the cache and the pool. This will be fixed [WHEN?], but
+ the speed of allocation with a debug class will always be
+ similar to :c:func:`mps_alloc`, rather than cached speed.
+
+
+
+
+Example
+
+
+ res = mps_sac_create(&sac, pool, 3, classes);
+ if (res != MPS_RES_OK) {
+ printf("Failed to create the allocation cache!");
+ exit(1);
+ }
+
+ /* Use sac. */
+
+ mps_sac_destroy(sac);
+ mps_pool_destroy(pool);
+
+
+
+
+
+Example
+
+
+ mps_sac_t sac_small, sac_large;
+
+ res = mps_sac_create(&sac_small, pool, 3, small_classes);
+ if (res != MPS_RES_OK) {
+ printf("Failed to create the small allocation cache!");
+ exit(1);
+ }
+
+ res = mps_sac_create(&sac_large, pool, 3, large_classes);
+ if (res != MPS_RES_OK) {
+ printf("Failed to create the large allocation cache!");
+ exit(1);
+ }
+
+ /* Use sac_small. */
+
+ mps_sac_flush(sac_small);
+
+ /* Use sac_large. */
+
+ mps_sac_flush(sac_large);
+
+ /* Use sac_small. */
+
+
+
+
+
+Example
+
+
+ mps_sac_t sac;
+ mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
+
+ res = mps_sac_create(&sac, pool, 3, classes);
+ if (res != MPS_RES_OK) {
+ printf("Failed to create the allocation cache!");
+ exit(1);
+ }
+
+
diff --git a/mps/manual/source/topic/collection.rst b/mps/manual/source/topic/collection.rst
new file mode 100644
index 00000000000..e3d2be29d40
--- /dev/null
+++ b/mps/manual/source/topic/collection.rst
@@ -0,0 +1,8 @@
+.. _topic-collection:
+
+==================
+Garbage collection
+==================
+
+
+
diff --git a/mps/manual/source/topic/debugging.rst b/mps/manual/source/topic/debugging.rst
new file mode 100644
index 00000000000..083660b06ce
--- /dev/null
+++ b/mps/manual/source/topic/debugging.rst
@@ -0,0 +1,18 @@
+.. _topic-debugging:
+
+===============
+Debugging pools
+===============
+
+
+Example
+
+
+static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 };
+if(mps_pool_create(&pool, arena, mps_class_ams_debug(),
+ &debugOptions, 8192, 135, 8)
+ != MPS_RES_OK) {
+ printf("Error creating pool!"); exit(2);
+}
+
+
diff --git a/mps/manual/source/topic/error.rst b/mps/manual/source/topic/error.rst
index ed9d6368196..7d3d8a5524f 100644
--- a/mps/manual/source/topic/error.rst
+++ b/mps/manual/source/topic/error.rst
@@ -34,3 +34,21 @@ Error handing
}
+
+
+
+
+Example
+
+
+mps_addr_t p;
+mps_res_t res;
+
+res = mps_alloc(&p, pool, sizeof(struct spong));
+if(res != MPS_RES_OK) {
+ handle_memory_error(res);
+ abort();
+}
+
+
+For more examples, s ee doc.mps.ref-man.if-conv.
diff --git a/mps/manual/source/topic/finalization.rst b/mps/manual/source/topic/finalization.rst
index b54ca899b87..4263cae5764 100644
--- a/mps/manual/source/topic/finalization.rst
+++ b/mps/manual/source/topic/finalization.rst
@@ -19,3 +19,21 @@ Note that there is no guarantee that finalization will be prompt.
Note that there will be no attempt to finalize objects in the context of :c:func:`mps_arena_destroy` or :c:func:`mps_pool_destroy`. :c:func:`mps_pool_destroy` should therefore not be invoked on pools containing objects registered for finalization.
Not all pool classes support finalization of objects. In general only pools that manage objects whose liveness is determined by garbage collection will support finalization of objects. For more information, see the Pool Class Catalog.
+
+
+
+Example
+
+
+{
+ mps_message_type_t type;
+
+ if(mps_message_queue_type(&type, arena)) {
+ if(type == mps_message_type_finalization()) {
+ process_finalization_message_from_queue();
+ } else {
+ unknown_message_type();
+ }
+ }
+}
+
diff --git a/mps/manual/source/topic/index.rst b/mps/manual/source/topic/index.rst
index d3efc1b0ef4..cddc5900376 100644
--- a/mps/manual/source/topic/index.rst
+++ b/mps/manual/source/topic/index.rst
@@ -7,6 +7,7 @@ Topic reference
arena
allocation
+ collection
error
format
scanning
@@ -20,3 +21,5 @@ Topic reference
platform
telemetry
message
+ debugging
+
diff --git a/mps/manual/source/topic/message.rst b/mps/manual/source/topic/message.rst
index c6bf867c32a..394e2e7a356 100644
--- a/mps/manual/source/topic/message.rst
+++ b/mps/manual/source/topic/message.rst
@@ -18,3 +18,33 @@ Messages
printf("Collection started at %ul.\n", (unsigned long)posted_at);
}
+
+
+
+Example
+
+
+{
+ mps_message_t message;
+ if(mps_message_get(&message, arena, mps_message_type_gc())) {
+ size_t live, condemned, not_condemned;
+ live = mps_message_gc_live_size(arena, message);
+ condemned = mps_message_gc_condemned_size(arena, message);
+ not_condemned = mps_message_gc_not_condemned_size(arena,message);
+ mps_message_discard(arena, message);
+ process_collection_stats(live, condemned, not_condemned);
+ }
+}
+
+
+
+
+
+{
+ mps_message_t message;
+ if(mps_message_get(&message, arena, mps_message_type_gc_start())) {
+ printf("Collection started; reason: %s\n",
+ mps_message_gc_start_why(arena, message));
+ }
+}
+
diff --git a/mps/manual/source/topic/root.rst b/mps/manual/source/topic/root.rst
index 1956a74fdad..70ed52ef0ee 100644
--- a/mps/manual/source/topic/root.rst
+++ b/mps/manual/source/topic/root.rst
@@ -25,3 +25,220 @@ unprotect the relevant pages.
This feature is far too technical for most of our clients: we should think about producing some guidelines on how to use it. - pekka 1998-01-27
There may be problems if the client wants the OS to access the root. Lots of OSes can't cope with writing to protected pages. So we'll need to document that caveat too. drj 1998-05-20
+ + + +
+static mps_root_t mmRoot;
+
+int main(void)
+{
+ mps_res_t res;
+
+ /* ... */
+
+ res = mps_root_create(&mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
+ &rootScanner, NULL, 0);
+ /* see doc of mps_root_scan_t for definition of rootScanner */
+ if(res != MPS_RES_OK)
+ exit(1);
+
+ /* ... */
+}
+
+
+
+
+
+ .. note::
+
+ Unless the rank of the root is not :c:macro:`MPS_RANK_AMBIG`,
+ the contents of the root have to be valid whenever a
+ :term:`garbage collection` happens. That is, all the
+ references fixed by the root scanning function have to be
+ references to actual objects or null pointers. If you're using
+ :term:`asynchronous` garbage collection, this could be as soon
+ as the root is registered, so the root has to be valid when it
+ is registered. As with an ordinary :term:`scan method`, a root
+ scanning function is allowed to fix references which point to
+ memory not managed by the MPS. These references will be
+ ignored.
+
+
+
+
+
+static mps_root_t mmRoot;
+SegmentDescriptor DataSegment;
+
+int main(void)
+{
+ mps_res_t res;
+
+ /* ... */
+
+ res = mps_root_create_fmt(&mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
+ &scan_objs,
+ (mps_addr_t)DataSegment.base,
+ (mps_addr_t) (DataSegment.base + SegmentLength) );
+
+ /* see doc of mps_fmt_scan_t for definition of scan_objs */
+
+ if(res != MPS_RES_OK)
+ exit( EXIT_FAILURE );
+
+ /* ... */
+}
+
+
+
+
+
+
+
+typedef struct {
+ mps_root_t mmRoot;
+ mps_thr_t thread;
+ /* ... */
+} ThreadLocals;
+
+void InitThread(ThreadLocals *thr)
+{
+ /* This is a hack to find the bottom of the stack. */
+ void *stackBottom=&stackBottom;
+
+ mps_thread_reg(&thr->thread, arena);
+ mps_root_create_reg(&thr->mmRoot, arena, MPS_RANK_AMBIG, (mps_rm_t) 0,
+ thr->thread, mps_stack_scan_ambig, stackBottom, 0);
+
+ /* ... */
+
+}
+
+
+
+
+
+
+
+
+static mps_root_t mmRoot;
+Object *Objects[rootCOUNT];
+
+int main(void)
+{
+ mps_res_t res;
+
+ /* ... */
+
+ res = mps_root_create_table(&mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
+ (mps_addr_t) &Objects, rootCOUNT );
+
+ if(res != MPS_RES_OK)
+ exit(1);
+
+ /* ... */
+}
+
+
+
+
+
+
+#define tagMASK 0x0003
+
+static mps_root_t mmRoot;
+Object *Objects[rootCOUNT];
+
+int main(void)
+{
+ mps_res_t res;
+
+ /* ... */
+
+ res = mps_root_create_table_masked(&mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
+ (mps_addr_t)&Objects, rootCOUNT,
+ (mps_word_t)tagMASK);
+ if(res != MPS_RES_OK)
+ exit(1);
+
+ /* ... */
+}
+
+
+
+
+
+
+
+static StackFrame *stackBottom;
+
+/* root scanner for an imaginary interpreter for a stack-oriented language */
+static mps_res_t rootScanner(mps_ss_t ss, void * p, size_t s)
+{
+ StackFrame *frame;
+ size_t i;
+ mps_res_t res;
+
+ UNUSED(p);
+ UNUSED(s);
+
+ for(frame = stackBottom; frame != NULL; frame = frame->next)
+ for(i = frame->size; i > 0; --i) {
+ res = mps_fix(ss, &frame->locals[i]);
+ if(res != MPS_RES_OK) return res;
+ }
+
+ return res;
+}
+
+
+
+
+
+
+
+typedef struct {
+ mps_root_t mmRoot;
+ mps_thr_t thread;
+ /* ... */
+} ThreadLocals;
+
+void InitThread(ThreadLocals *thr)
+{
+ /* This is a hack to find the bottom of the stack. */
+ void *stackBottom=&stackBottom;
+
+ mps_thread_reg(&thr->thread, arena);
+ mps_root_create_reg(&thr->mmRoot, arena, MPS_RANK_AMBIG, (mps_rm_t)0,
+ thr->thread, mps_stack_scan_ambig, stackBottom, 0)
+
+ /* ... */
+}
+
+
+
+
++ mps_thr_t this_thread; + mps_res_t res; + + res = mps_thread_reg(&this_thread, space); + if(res != MPS_RES_OK) return res; +diff --git a/mps/manual/source/topic/telemetry.rst b/mps/manual/source/topic/telemetry.rst index f3cd615f141..df0a7bc038e 100644 --- a/mps/manual/source/topic/telemetry.rst +++ b/mps/manual/source/topic/telemetry.rst @@ -3,3 +3,9 @@ ========= Telemetry ========= + +Typical uses of telemtry labels include: + +- Label pools with a human-meaningful name; + +- Label allocated objects with their type or class.