]> Zhao Yanbai Git Server - minix.git/commitdiff
Rearrange endpoint number layout
authorDavid van Moolenbroek <david@minix3.org>
Tue, 25 Feb 2014 13:24:52 +0000 (14:24 +0100)
committerLionel Sambuc <lionel@minix3.org>
Mon, 28 Jul 2014 15:05:12 +0000 (17:05 +0200)
The constants ANY, NONE, and SELF are now a function of the way the
endpoint number is split between a generation number and a process
slot number, rather than the other way around.  This allows for the
use of bit masking and shifting instead of the previous (and more
expensive) multiplication and division.

Change-Id: Id890eea74435444128c75eb0c89816b948f43c0b

include/lib.h
include/minix/com.h
include/minix/endpoint.h
test/test39.c

index f3df2951ffb9c2351a7ca903011e2c60e4cffe29..e5e1d258261a0686f52c065904912296c4294e64 100644 (file)
@@ -18,7 +18,7 @@
 #include <minix/com.h>
 #include <minix/type.h>
 #include <minix/callnr.h>
-
+#include <minix/endpoint.h>
 #include <minix/ipc.h>
 
 struct ps_strings; /* forward declaration for minix_stack_fill. */
index d63545452b232a1ee39c6d6a03c8f17b979eb07a..219345c0aa94fa3c18d353163cc67f83a457cb6e 100644 (file)
 #ifndef _MINIX_COM_H
 #define _MINIX_COM_H 
 
-/*===========================================================================*
- *                             Magic process numbers                        *
- *===========================================================================*/
-
-/* These may not be any valid endpoint (see <minix/endpoint.h>). */
-#define ANY    ((endpoint_t) 0x7ace)   /* used to indicate 'any process' */
-#define NONE   ((endpoint_t) 0x6ace)   /* used to indicate 'no process at all' */
-#define SELF   ((endpoint_t) 0x8ace)   /* used to indicate 'own process' */
-#define _MAX_MAGIC_PROC (SELF) /* used by <minix/endpoint.h> 
-                                  to determine generation size */
-
 /*===========================================================================*
  *             Process numbers of processes in the system image             *
  *===========================================================================*/
 
-/* The values of several task numbers depend on whether they or other tasks
- * are enabled. They are defined as (PREVIOUS_TASK - ENABLE_TASK) in general.
- * ENABLE_TASK is either 0 or 1, so a task either gets a new number, or gets
- * the same number as the previous task and is further unused. Note that the
- * order should correspond to the order in the task table defined in table.c. 
- */
-
 /* Kernel tasks. These all run in the same address space. */
 #define ASYNCM ((endpoint_t) -5) /* notifies about finished async sends */
 #define IDLE    ((endpoint_t) -4) /* runs when no one else can run */
index 54dc7b9d66566f86e0652c24eb1a8a72dd9dd383..0cf3f3bb7f73a7bcc2c24eaaf1cc8c0711aca81e 100644 (file)
@@ -7,22 +7,65 @@
 #include <limits.h>
 #include <minix/type.h>
 
-/* The point of the padding in 'generation size' is to 
- * allow for certain bogus endpoint numbers such as NONE, ANY, etc.
+/*
+ * Endpoints are split into two parts: a process slot and a generation number.
  *
- * The _MAX_MAGIC_PROC is defined by <minix/com.h>. That include
- * file defines some magic process numbers such as ANY and NONE,
- * and must never be a valid endpoint number. Therefore we make sure
- * the generation size is big enough to start the next generation
- * above the highest magic number.
+ * The process slot number identifies the slot in various process tables.
+ * It is positive or zero for user processes, and negative for kernel tasks.
+ * Constants dictate that with the current endpoint layout, the maximum range
+ * of process slot numbers is [-MAX_NR_TASKS,MAX_NR_PROCS>.  The used part of
+ * the range is currently [-NR_TASKS,NR_PROCS> -- these two constants may be
+ * changed within the maximum range without changing the endpoint layout.
+ *
+ * The generation number is a per-slot number that gets increased by one every
+ * time a slot is reused for a new process.  The generation number minimizes
+ * the chance that the endpoint of a dead process can (accidentially) be used
+ * to communicate with a different, live process.  Preventing such accidents
+ * is essential for proper system service restartability support.
+ *
+ * The split between the two parts of the endpoint is such that when the
+ * generation number is zero, the endpoint number equals the process slot
+ * number, even for negative task numbers.  This is required for the endpoint
+ * numbers hardcoded in <minix/com.h>, and it makes endpoint numbers easy to
+ * read in general.
+ *
+ * There are three special endpoint numbers: ANY, NONE, and SELF.  These
+ * numbers are used to identify "any process", "no process at all", and
+ * "own process", respectively.  They fall outside the normal range of
+ * process slot numbers, and are always of generation zero.
+ */
+
+/*
+ * The following constant defines the split between the two parts of the
+ * endpoint numbers.  It can be adjusted to allow for either more processes
+ * or more per-process generation numbers.  Changing it will change the
+ * endpoint number layout, and thus break binary compatibility with existing
+ * processes.
  */
-#define _ENDPOINT_GENERATION_SIZE (MAX_NR_TASKS+_MAX_MAGIC_PROC+1)
-#define _ENDPOINT_MAX_GENERATION  (INT_MAX/_ENDPOINT_GENERATION_SIZE-1)
+#define _ENDPOINT_GENERATION_SHIFT     15
+
+/* Derived constants. */
+#define _ENDPOINT_GENERATION_SIZE      (1 << _ENDPOINT_GENERATION_SHIFT)
+/* INT_MAX is used here to prevent signedness issues with the macros below. */
+#define _ENDPOINT_MAX_GENERATION       (INT_MAX/_ENDPOINT_GENERATION_SIZE-1)
+#define _ENDPOINT_SLOT_TOP     (_ENDPOINT_GENERATION_SIZE-MAX_NR_TASKS)
+
+/* The special endpoint numbers, and the resulting maximum slot number. */
+#define ANY            ((endpoint_t) (_ENDPOINT_SLOT_TOP - 1))
+#define NONE           ((endpoint_t) (_ENDPOINT_SLOT_TOP - 2))
+#define SELF           ((endpoint_t) (_ENDPOINT_SLOT_TOP - 3))
+#define MAX_NR_PROCS                 (_ENDPOINT_SLOT_TOP - 3)  /* (int)SELF */
+
+/* Sanity check. */
+#if NR_PROCS > MAX_NR_PROCS
+#error "NR_PROCS exceeds MAX_NR_PROCS, increase _ENDPOINT_GENERATION_SHIFT"
+#endif
 
 /* Generation + Process slot number <-> endpoint. */
-#define _ENDPOINT(g, p) ((endpoint_t)((g) * _ENDPOINT_GENERATION_SIZE + (p)))
-#define _ENDPOINT_G(e) (((e)+MAX_NR_TASKS) / _ENDPOINT_GENERATION_SIZE)
+#define _ENDPOINT(g, p) \
+       ((endpoint_t)(((g) << _ENDPOINT_GENERATION_SHIFT) + (p)))
+#define _ENDPOINT_G(e) (((e)+MAX_NR_TASKS) >> _ENDPOINT_GENERATION_SHIFT)
 #define _ENDPOINT_P(e) \
-       ((((e)+MAX_NR_TASKS) % _ENDPOINT_GENERATION_SIZE) - MAX_NR_TASKS)
+       ((((e)+MAX_NR_TASKS) & (_ENDPOINT_GENERATION_SIZE - 1)) - MAX_NR_TASKS)
 
 #endif
index 05b143e947c83b10b709ea22bbee5d58e18bdaad..0ec2931c35145eefb32b15bd402a5329e895241e 100644 (file)
@@ -23,7 +23,7 @@ void test39a()
   subtest = 1;
 
   for (g = 0; g <= _ENDPOINT_MAX_GENERATION; g++) {
-       for (p = -MAX_NR_TASKS; p < _NR_PROCS; p++) {
+       for (p = -MAX_NR_TASKS; p < MAX_NR_PROCS; p++) {
                endpoint_t ept;
                int mg, mp;
                ept = _ENDPOINT(g, p);