<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[23147] trunk/launchd/src/launchd_core_logic.c</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.macosforge.org/projects/launchd/changeset/23147">23147</a></dd>
<dt>Author</dt> <dd>zarzycki@apple.com</dd>
<dt>Date</dt> <dd>2007-03-08 15:34:00 -0800 (Thu, 08 Mar 2007)</dd>
</dl>

<h3>Log Message</h3>
<pre>Let's ditch the old reordring of the job_t list MRU hack in favor of an actual hash based lookup.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunklaunchdsrclaunchd_core_logicc">trunk/launchd/src/launchd_core_logic.c</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunklaunchdsrclaunchd_core_logicc"></a>
<div class="modfile"><h4>Modified: trunk/launchd/src/launchd_core_logic.c (23146 => 23147)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/launchd/src/launchd_core_logic.c        2007-03-08 23:01:26 UTC (rev 23146)
+++ trunk/launchd/src/launchd_core_logic.c        2007-03-08 23:34:00 UTC (rev 23147)
</span><span class="lines">@@ -193,11 +193,16 @@
</span><span class="cx"> static void semaphoreitem_watch(job_t j, struct semaphoreitem *si);
</span><span class="cx"> static void semaphoreitem_ignore(job_t j, struct semaphoreitem *si);
</span><span class="cx"> 
</span><ins>+#define IS_POWER_OF_TWO(v)        (!(v &amp; (v - 1)) &amp;&amp; v)
+#define ACTIVE_JOB_HASH_SIZE        32
+#define ACTIVE_JOB_HASH(x)        (IS_POWER_OF_TWO(ACTIVE_JOB_HASH_SIZE) ? (x &amp; (ACTIVE_JOB_HASH_SIZE - 1)) : (x % ACTIVE_JOB_HASH_SIZE))
+
</ins><span class="cx"> struct jobmgr_s {
</span><span class="cx">         kq_callback kqjobmgr_callback;
</span><span class="cx">         SLIST_ENTRY(jobmgr_s) sle;
</span><span class="cx">         SLIST_HEAD(, jobmgr_s) submgrs;
</span><del>-        TAILQ_HEAD(, job_s) jobs;
</del><ins>+        SLIST_HEAD(, job_s) jobs;
+        SLIST_HEAD(, job_s) active_jobs[ACTIVE_JOB_HASH_SIZE];
</ins><span class="cx">         mach_port_t jm_port;
</span><span class="cx">         mach_port_t req_port;
</span><span class="cx">         jobmgr_t parentmgr;
</span><span class="lines">@@ -230,7 +235,8 @@
</span><span class="cx"> 
</span><span class="cx"> struct job_s {
</span><span class="cx">         kq_callback kqjob_callback;
</span><del>-        TAILQ_ENTRY(job_s) sle;
</del><ins>+        SLIST_ENTRY(job_s) sle;
+        SLIST_ENTRY(job_s) hash_sle;
</ins><span class="cx">         SLIST_HEAD(, socketgroup) sockets;
</span><span class="cx">         SLIST_HEAD(, calendarinterval) cal_intervals;
</span><span class="cx">         SLIST_HEAD(, envitem) global_env;
</span><span class="lines">@@ -545,7 +551,7 @@
</span><span class="cx">                 jobmgr_shutdown(jmi);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</del><ins>+        SLIST_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</ins><span class="cx">                 if (!job_active(ji)) {
</span><span class="cx">                         job_remove(ji);
</span><span class="cx">                 } else if (!ji-&gt;hopefully_exits_last) {
</span><span class="lines">@@ -575,15 +581,15 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         /* We should have one job left and it should be the anonymous job */
</span><del>-        ji = TAILQ_FIRST(&amp;jm-&gt;jobs);
</del><ins>+        ji = SLIST_FIRST(&amp;jm-&gt;jobs);
</ins><span class="cx">         if (!(jobmgr_assumes(jm, ji != NULL) &amp;&amp; jobmgr_assumes(jm, ji == jm-&gt;anonj)
</span><del>-                                &amp;&amp; jobmgr_assumes(jm, TAILQ_NEXT(ji, sle) == NULL))) {
-                TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+                                &amp;&amp; jobmgr_assumes(jm, SLIST_NEXT(ji, sle) == NULL))) {
+                SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                         job_log(ji, LOG_ERR, &quot;Still remaining at removal.&quot;);
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        while ((ji = TAILQ_FIRST(&amp;jm-&gt;jobs))) {
</del><ins>+        while ((ji = SLIST_FIRST(&amp;jm-&gt;jobs))) {
</ins><span class="cx">                 job_remove(ji);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -707,7 +713,7 @@
</span><span class="cx">         kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
</span><span class="cx"> 
</span><span class="cx">         if (job_assumes(j, j-&gt;mgr)) {
</span><del>-                TAILQ_REMOVE(&amp;j-&gt;mgr-&gt;jobs, j, sle);
</del><ins>+                SLIST_REMOVE(&amp;j-&gt;mgr-&gt;jobs, j, job_s, sle);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         job_log(j, LOG_DEBUG, &quot;Removed&quot;);
</span><span class="lines">@@ -998,7 +1004,7 @@
</span><span class="cx">                 j-&gt;argv[i] = NULL;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_INSERT_TAIL(&amp;jm-&gt;jobs, j, sle);
</del><ins>+        SLIST_INSERT_HEAD(&amp;jm-&gt;jobs, j, sle);
</ins><span class="cx"> 
</span><span class="cx">         job_log(j, LOG_DEBUG, &quot;Conceived&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -1518,7 +1524,7 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 if (strcmp(ji-&gt;label, label) == 0) {
</span><span class="cx">                         return ji;
</span><span class="cx">                 }
</span><span class="lines">@@ -1536,18 +1542,15 @@
</span><span class="cx"> 
</span><span class="cx">         if (jm-&gt;jm_port == p) {
</span><span class="cx">                 struct ldcred ldc;
</span><ins>+                pid_t hashp;
</ins><span class="cx"> 
</span><span class="cx">                 runtime_get_caller_creds(&amp;ldc);
</span><span class="cx"> 
</span><del>-                TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+                hashp = ACTIVE_JOB_HASH(ldc.pid);
+
+                SLIST_FOREACH(ji, &amp;jm-&gt;active_jobs[hashp], hash_sle) {
</ins><span class="cx">                         if (ji-&gt;p == ldc.pid) {
</span><del>-                                /* This is just a MRU perfomance hack */
-                                TAILQ_REMOVE(&amp;jm-&gt;jobs, ji, sle);
-                                TAILQ_INSERT_HEAD(&amp;jm-&gt;jobs, ji, sle);
</del><span class="cx">                                 return ji;
</span><del>-                        } else if (ji-&gt;p == 0) {
-                                /* All the PIDs are at the front of the list */
-                                break;
</del><span class="cx">                         }
</span><span class="cx">                 }
</span><span class="cx">                 return jm-&gt;anonj;
</span><span class="lines">@@ -1561,7 +1564,7 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 if (ji-&gt;j_port == p) {
</span><span class="cx">                         return ji;
</span><span class="cx">                 }
</span><span class="lines">@@ -1593,7 +1596,7 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 SLIST_FOREACH(ms, &amp;ji-&gt;machservices, sle) {
</span><span class="cx">                         if (ms-&gt;port == p) {
</span><span class="cx">                                 return ji;
</span><span class="lines">@@ -1619,7 +1622,7 @@
</span><span class="cx">                 job_export_all2(jmi, where);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 launch_data_t tmp;
</span><span class="cx"> 
</span><span class="cx">                 if (jobmgr_assumes(jm, (tmp = job_export2(ji, false)) != NULL)) {
</span><span class="lines">@@ -1688,11 +1691,8 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         total_children--;
</span><ins>+        SLIST_REMOVE(&amp;j-&gt;mgr-&gt;active_jobs[ACTIVE_JOB_HASH(j-&gt;p)], j, job_s, hash_sle);
</ins><span class="cx"> 
</span><del>-        /* Performance hack */
-        TAILQ_REMOVE(&amp;j-&gt;mgr-&gt;jobs, j, sle);
-        TAILQ_INSERT_TAIL(&amp;j-&gt;mgr-&gt;jobs, j, sle);
-
</del><span class="cx">         job_assumes(j, gettimeofday(&amp;tve, NULL) != -1);
</span><span class="cx"> 
</span><span class="cx">         if (j-&gt;wait_reply_port) {
</span><span class="lines">@@ -1760,7 +1760,7 @@
</span><span class="cx">                 jobmgr_dispatch_all(jmi);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</del><ins>+        SLIST_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</ins><span class="cx">                 job_dispatch(ji, false);
</span><span class="cx">         }
</span><span class="cx"> }
</span><span class="lines">@@ -2025,11 +2025,8 @@
</span><span class="cx">                 break;
</span><span class="cx">         default:
</span><span class="cx">                 total_children++;
</span><ins>+                SLIST_INSERT_HEAD(&amp;j-&gt;mgr-&gt;active_jobs[ACTIVE_JOB_HASH(c)], j, hash_sle);
</ins><span class="cx"> 
</span><del>-                /* Performance hack */
-                TAILQ_REMOVE(&amp;j-&gt;mgr-&gt;jobs, j, sle);
-                TAILQ_INSERT_HEAD(&amp;j-&gt;mgr-&gt;jobs, j, sle);
-
</del><span class="cx">                 if (!j-&gt;legacy_mach_job) {
</span><span class="cx">                         job_assumes(j, close(oepair[1]) != -1);
</span><span class="cx">                 }
</span><span class="lines">@@ -2137,7 +2134,7 @@
</span><span class="cx">                 jobmgr_setup_env_from_other_jobs(jm-&gt;parentmgr);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 SLIST_FOREACH(ei, &amp;ji-&gt;global_env, sle) {
</span><span class="cx">                         setenv(ei-&gt;key, ei-&gt;value, 1);
</span><span class="cx">                 }
</span><span class="lines">@@ -3303,7 +3300,7 @@
</span><span class="cx">                 return jm;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 if (ji-&gt;p &amp;&amp; !ji-&gt;hopefully_exits_last) {
</span><span class="cx">                         return jm;
</span><span class="cx">                 }
</span><span class="lines">@@ -3311,7 +3308,7 @@
</span><span class="cx"> 
</span><span class="cx">         jobmgr_log(jm, LOG_DEBUG, &quot;Asking \&quot;hopeful\&quot; jobs to exit.&quot;);
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 job_stop(ji);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -3368,7 +3365,7 @@
</span><span class="cx">                 return false;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 if (ji-&gt;p) {
</span><span class="cx">                         return false;
</span><span class="cx">                 }
</span><span class="lines">@@ -3421,7 +3418,6 @@
</span><span class="cx">                 return NULL;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_INIT(&amp;jmr-&gt;jobs);
</del><span class="cx">         jmr-&gt;kqjobmgr_callback = jobmgr_callback;
</span><span class="cx">         strcpy(jmr-&gt;name, name ? name : &quot;Under construction&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -3540,7 +3536,7 @@
</span><span class="cx">                 jobmgr_delete_anything_with_port(jmi, port);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</del><ins>+        SLIST_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</ins><span class="cx">                 SLIST_FOREACH_SAFE(ms, &amp;ji-&gt;machservices, sle, next_ms) {
</span><span class="cx">                         if (ms-&gt;port == port) {
</span><span class="cx">                                 machservice_delete(ms);
</span><span class="lines">@@ -3565,7 +3561,7 @@
</span><span class="cx">                 jobmgr_assumes(jm, !check_parent);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 if (target_pid &amp;&amp; (ji-&gt;p != target_pid)) {
</span><span class="cx">                         continue;
</span><span class="cx">                 }
</span><span class="lines">@@ -3728,7 +3724,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         /* We don't need the _SAFE version because we return after the job_dispatch() */
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 SLIST_FOREACH(ms, &amp;ji-&gt;machservices, sle) {
</span><span class="cx">                         if (ms-&gt;port != p) {
</span><span class="cx">                                 continue;
</span><span class="lines">@@ -3947,7 +3943,7 @@
</span><span class="cx">                 jobmgr_dispatch_all_semaphores(jmi);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</del><ins>+        SLIST_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</ins><span class="cx">                 if (!SLIST_EMPTY(&amp;ji-&gt;semaphores)) {
</span><span class="cx">                         job_dispatch(ji, false);
</span><span class="cx">                 }
</span><span class="lines">@@ -4313,7 +4309,7 @@
</span><span class="cx"> 
</span><span class="cx">         *up_cont = MACH_PORT_NULL;
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;root_jobmgr-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;root_jobmgr-&gt;jobs, sle) {
</ins><span class="cx">                 if (ji-&gt;mach_uid != which_user) {
</span><span class="cx">                         continue;
</span><span class="cx">                 }
</span><span class="lines">@@ -4538,7 +4534,7 @@
</span><span class="cx"> 
</span><span class="cx">         jm = j-&gt;mgr;
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 SLIST_FOREACH(ms, &amp;ji-&gt;machservices, sle) {
</span><span class="cx">                         if (!ms-&gt;per_pid) {
</span><span class="cx">                                 cnt++;
</span><span class="lines">@@ -4560,7 +4556,7 @@
</span><span class="cx">                 goto out_bad;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        TAILQ_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</del><ins>+        SLIST_FOREACH(ji, &amp;jm-&gt;jobs, sle) {
</ins><span class="cx">                 SLIST_FOREACH(ms, &amp;ji-&gt;machservices, sle) {
</span><span class="cx">                         if (!ms-&gt;per_pid) {
</span><span class="cx">                                 strlcpy(service_names[cnt2], machservice_name(ms), sizeof(service_names[0]));
</span><span class="lines">@@ -4610,8 +4606,8 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (job_assumes(j, jmi != NULL)) {
</span><del>-                TAILQ_REMOVE(&amp;j-&gt;mgr-&gt;jobs, j, sle);
-                TAILQ_INSERT_TAIL(&amp;jmi-&gt;jobs, j, sle);
</del><ins>+                SLIST_REMOVE(&amp;j-&gt;mgr-&gt;jobs, j, job_s, sle);
+                SLIST_INSERT_HEAD(&amp;jmi-&gt;jobs, j, sle);
</ins><span class="cx">                 j-&gt;mgr = jmi;
</span><span class="cx">         }
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>