Removed event overflow handling
[akaros.git] / Documentation / process-internals.txt
index 3e6bcb8..87b9c73 100644 (file)
@@ -26,8 +26,8 @@ to Linux's kref:
   already a reference to it.  It is a bug to try to incref on something that has
   no references, so always make sure you incref something that you know has a
   reference.  If you don't know, you need to get it from pid2proc (which is a
-  careful way of doing this).  pid2proc kref_get()s on the reference that is
-  stored inside it.  If you incref and there are 0 references, the kernel will
+  careful way of doing this - pid2proc kref_get_not_zero()s on the reference that is
+  stored inside it).  If you incref and there are 0 references, the kernel will
   panic.  Fix your bug / don't incref random pointers.
 - Can always decref.
 - When the decref returns 0, perform some operation.  This does some final
@@ -59,11 +59,14 @@ protected by a refcnt.
 +1 for existing.
 - The fact that the process is supposed to exist is worth +1.  When it is time
   to die, we decref, and it will eventually be cleaned up.  This existence is
-  based on it's presence in the hash table, which is a stored reference.
-- The hash table is a bit tricky.  We need to kref_get() when it is locked, so
-  we know we have a valid kref to get.  We don't need to lock the list to
-  kref_put the process, since once it is removed from the hash, we now own that
-  reference.  
+  explicitly kref_put()d in proc_destroy().
+- The hash table is a bit tricky.  We need to kref_get_not_zero() when it is
+  locked, so we know we aren't racing with proc_free freeing the proc and
+  removing it from the list.  After removing it from the hash, we don't need to
+  kref_put it, since it was an internal ref.  The kref (i.e. external) isn't for
+  being on the hash list, it's for existing.  This separation allows us to
+  remove the proc from the hash list in the "release" function.  See kref.txt
+  for more details.
 
 +1 for someone using it or planning to use it.
 - This includes simply having a pointer to the proc, since presumably you will
@@ -76,7 +79,11 @@ protected by a refcnt.
 
 +1 for current.
 - current counts as someone using it (expressing interest in the core), but is
-  also a source of the pointer, so its a bit different.
+  also a source of the pointer, so its a bit different.  Note that all kref's
+  are sources of a pointer.  Technically, to even use 'current', we should kref
+  it and pass it around as a proc.  We don't for performance reasons.  When we
+  are running on a core that has current loaded, the ref is both for its usage
+  as well as for being the current process.
 - You have a reference from current and can use it without refcnting, but
   anything that needs to eat a reference or store/use it needs an incref first.
   To be clear, your reference is *NOT* edible.  It protects the cr3, guarantees
@@ -85,8 +92,9 @@ protected by a refcnt.
   an IO continuation request), then clearly you must incref, since it's both
   current and stored/used.
 - If you don't know what might be downstream from your function, then incref
-  before passing the reference, and decref when it returns.  Like when handling
-  syscalls, for example.
+  before passing the reference, and decref when it returns.  We used to do this
+  for all syscalls, but now only do it for calls that might not return and
+  expect to receive reference (like proc_yield).
 
 All functions that take a *proc have a refcnt'd reference, though it may not be
 edible (it could be current).  It is the callers responsibility to make sure
@@ -105,6 +113,11 @@ This means that you must have a reference when you call them (like always), and
 that reference will be consumed / decref'd for you if the function doesn't
 return.  Or something similarly appropriate.
 
+Arguably, for functions that MAY not return, but will always be called with
+current's reference (proc_yield()), we could get away without giving it an
+edible reference, and then never eating the ref.  Yield needs to be reworked
+anyway, so it's not a bit deal yet.
+
 We do this because when the function does not return, you will not have the
 chance to decref (your decref code will never run).  We need the reference when
 going in to keep the object alive (like with any other refcnt).  We can't have