[launchd-changes] [23804] branches/PR-5063531/launchd/src

source_changes at macosforge.org source_changes at macosforge.org
Thu Feb 12 20:20:18 PST 2009


Revision: 23804
          http://trac.macosforge.org/projects/launchd/changeset/23804
Author:   dsorresso at apple.com
Date:     2009-02-12 20:20:18 -0800 (Thu, 12 Feb 2009)
Log Message:
-----------
Implemented boot plist caching. We're saving about 0.6 seconds.

Modified Paths:
--------------
    branches/PR-5063531/launchd/src/launchctl.c
    branches/PR-5063531/launchd/src/launchd_core_logic.c

Modified: branches/PR-5063531/launchd/src/launchctl.c
===================================================================
--- branches/PR-5063531/launchd/src/launchctl.c	2009-02-12 20:48:11 UTC (rev 23803)
+++ branches/PR-5063531/launchd/src/launchctl.c	2009-02-13 04:20:18 UTC (rev 23804)
@@ -81,6 +81,7 @@
 #include <util.h>
 #include <spawn.h>
 #include <sys/syslimits.h>
+#include <mach/mach_time.h>
 
 #if HAVE_LIBAUDITD
 #include <bsm/auditd_lib.h>
@@ -89,9 +90,10 @@
 #endif
 #endif
 
+#define LAUNCHD_PLIST_CACHE "/var/db/launchd_plist_cache.plist"
+
 extern char **environ;
 
-
 #define LAUNCH_SECDIR _PATH_TMP "launch-XXXXXX"
 
 #define MACHINIT_JOBKEY_ONDEMAND	"OnDemand"
@@ -125,7 +127,7 @@
 static launch_data_t read_plist_file(const char *file, bool editondisk, bool load);
 static CFPropertyListRef CreateMyPropertyListFromFile(const char *);
 static CFPropertyListRef CFPropertyListCreateFromFile(CFURLRef plistURL);
-static void WriteMyPropertyListToFile(CFPropertyListRef, const char *);
+static void WriteMyPropertyListToFile(CFPropertyListRef, const char *, bool);
 static bool path_goodness_check(const char *path, bool forceload);
 static void readpath(const char *, struct load_unload_state *);
 static void readfile(const char *, struct load_unload_state *);
@@ -257,6 +259,10 @@
 static bool rootuser_context;
 static bool g_shutdown_debugging = false;
 
+static uint32_t g_plist_cache_changes = 0;
+static time_t g_cache_creation_time = 0;
+static CFMutableDictionaryRef g_plist_cache = NULL;
+
 int
 main(int argc, char *const argv[])
 {
@@ -693,21 +699,56 @@
 launch_data_t
 read_plist_file(const char *file, bool editondisk, bool load)
 {
-	CFPropertyListRef plist = CreateMyPropertyListFromFile(file);
+	CFPropertyListRef plist = NULL;
+	bool add_to_cache = false, file_changed = false;
+	
+	CFStringRef key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), file);
+
+	struct stat sb;
+	if( assumes(stat(file, &sb) == 0) ) {
+		file_changed = sb.st_mtimespec.tv_sec > g_cache_creation_time;
+		if( file_changed ) {
+			fprintf(stdout, "File %s has changed.\n", file);
+		}
+	}
+	
+	if( g_plist_cache && !file_changed ) {
+		plist = CFDictionaryGetValue(g_plist_cache, key);
+		
+		if( plist && CFGetTypeID(plist) == CFDictionaryGetTypeID() ) {
+			CFRetain(plist);
+		} else {
+			fprintf(stdout, "Invalidating cache for %s...\n", file);
+			add_to_cache = true;
+		}
+	} else if( g_plist_cache ) {
+		add_to_cache = true;
+	}
+
+	if( !plist ) {
+		plist = CreateMyPropertyListFromFile(file);
+	}
+
 	launch_data_t r = NULL;
 
 	if (NULL == plist) {
 		fprintf(stderr, "%s: no plist was returned for: %s\n", getprogname(), file);
 		return NULL;
+	} else if( add_to_cache ) {
+		fprintf(stdout, "\tAdding %s to cache...\n", file);
+		CFDictionarySetValue(g_plist_cache, key, plist);
+		g_plist_cache_changes++;
 	}
 
+	CFRelease(key);
+
 	if (editondisk) {
 		if (load) {
 			CFDictionaryRemoveValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED));
 		} else {
 			CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR(LAUNCH_JOBKEY_DISABLED), kCFBooleanTrue);
 		}
-		WriteMyPropertyListToFile(plist, file);
+		WriteMyPropertyListToFile(plist, file, false);
 	}
 
 	r = CF2launch_data(plist);
@@ -1405,27 +1446,43 @@
 }
 
 void
-WriteMyPropertyListToFile(CFPropertyListRef plist, const char *posixfile)
+WriteMyPropertyListToFile(CFPropertyListRef plist, const char *posixfile, bool binary)
 {
-	CFDataRef	resourceData;
 	CFURLRef	fileURL;
-	SInt32		errorCode;
 
+	fprintf(stdout, "About to call CFURLCreateFromFileSystemRepresentation()...\n");
 	fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false);
 	if (!fileURL) {
-		fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile);
+		fprintf(stdout, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile);
 	}
+	
+#if 1
+	CFWriteStreamRef ws = CFWriteStreamCreateWithFile(NULL, fileURL);
+	if( ws ) {
+		if( assumes(CFWriteStreamOpen(ws) == true) ) {
+			assumes(CFPropertyListWriteToStream(plist, ws, binary ? kCFPropertyListBinaryFormat_v1_0 : kCFPropertyListXMLFormat_v1_0, NULL));
+			CFWriteStreamClose(ws);
+		}
+		CFRelease(ws);
+	}
+#else
+	SInt32		errorCode;
+	CFDataRef	resourceData;
+	fprintf(stdout, "About to call CFPropertyListCreateXMLData()...\n");
 	resourceData = CFPropertyListCreateXMLData(kCFAllocatorDefault, plist);
 	if (resourceData == NULL) {
-		fprintf(stderr, "%s: CFPropertyListCreateXMLData(%s) failed", getprogname(), posixfile);
+		fprintf(stdout, "%s: CFPropertyListCreateXMLData(%s) failed", getprogname(), posixfile);
 	}
+	
+	fprintf(stdout, "About to call CFURLWriteDataAndPropertiesToResource()...\n");
 	if (!CFURLWriteDataAndPropertiesToResource(fileURL, resourceData, NULL, &errorCode)) {
-		fprintf(stderr, "%s: CFURLWriteDataAndPropertiesToResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode);
+		fprintf(stdout, "%s: CFURLWriteDataAndPropertiesToResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode);
 	}
 	
 	if( resourceData ) {
 		CFRelease(resourceData);
 	}
+#endif
 }
 
 static inline Boolean __is_launch_data_t(launch_data_t obj) 
@@ -1908,11 +1965,34 @@
 	int load_launchd_items_cnt = 5;
 #endif
 
+	struct stat sb;
 	if (is_safeboot()) {
 		load_launchd_items[2] = "system";
+	} else if( stat("/var/db/.launchd_disable_plist_cache", &sb) != 0 ) {
+		CFDictionaryRef plist_cache = (CFDictionaryRef)CreateMyPropertyListFromFile(LAUNCHD_PLIST_CACHE);
+		if( !plist_cache ) {
+			g_plist_cache = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+		} else {
+			if( assumes(stat(LAUNCHD_PLIST_CACHE, &sb) == 0) ) {
+				g_cache_creation_time = sb.st_mtimespec.tv_sec;
+			}
+			
+			g_plist_cache = CFDictionaryCreateMutableCopy(NULL, 0, plist_cache);
+			CFRelease(plist_cache);
+		}
 	}
 
+	uint64_t t0 = mach_absolute_time();
 	assumes(load_and_unload_cmd(load_launchd_items_cnt, load_launchd_items) == 0);
+	uint64_t t1 = mach_absolute_time();
+	
+	fprintf(stdout, "It took %llu nanoseconds to load System jobs%s.\n", t1 - t0, !g_plist_cache ? " without the cache" : "");
+	syslog(LOG_NOTICE, "It took %llu nanoseconds to load System jobs%s.\n", t1 - t0, !g_plist_cache ? " without the cache" : "");
+	
+	if( g_plist_cache_changes > 0 ) {
+		fprintf(stdout, "Updating %u entries in launchd's plist cache.\n", g_plist_cache_changes);
+		WriteMyPropertyListToFile(g_plist_cache, LAUNCHD_PLIST_CACHE, true);
+	}
 
 	/*
 	 * 5066316

Modified: branches/PR-5063531/launchd/src/launchd_core_logic.c
===================================================================
--- branches/PR-5063531/launchd/src/launchd_core_logic.c	2009-02-12 20:48:11 UTC (rev 23803)
+++ branches/PR-5063531/launchd/src/launchd_core_logic.c	2009-02-13 04:20:18 UTC (rev 23804)
@@ -23,6 +23,7 @@
 
 #include <TargetConditionals.h>
 #include <mach/mach.h>
+#include <mach/clock_types.h>
 #include <mach/mach_error.h>
 #include <mach/boolean.h>
 #include <mach/message.h>
@@ -613,7 +614,6 @@
 static char **mach_cmd2argv(const char *string);
 static size_t our_strhash(const char *s) __attribute__((pure));
 static void extract_rcsid_substr(const char *i, char *o, size_t osz);
-static void do_first_per_user_launchd_hack(void);
 static void simulate_pid1_crash(void);
 static pid_t spawn_sync(job_t j);
 static pid_t basic_spawn(job_t j, void (*what_to_do)(job_t));
@@ -631,8 +631,6 @@
 static size_t total_children;
 static size_t total_anon_children;
 static mach_port_t the_exception_server;
-static bool did_first_per_user_launchd_BootCache_hack;
-#define JOB_BOOTCACHE_HACK_CHECK(j)	(unlikely(j->per_user && !did_first_per_user_launchd_BootCache_hack && (j->mach_uid >= 500) && (j->mach_uid != (uid_t)-2)))
 static job_t workaround_5477111;
 static pid_t s_update_pid = 0;
 
@@ -2470,6 +2468,10 @@
 		job_mig_swap_integer(j, VPROC_GSK_WEIRD_BOOTSTRAP, 0, 0, &junk);
 	}
 
+	if( unlikely(j->forced_peers_to_demand_mode) ) {
+		job_set_global_on_demand(j, false);
+	}
+
 	j->wait4debugger_oneshot = false;
 
 	if (j->log_redirect_fd && !j->legacy_LS_job) {
@@ -3510,10 +3512,6 @@
 		total_children++;
 		LIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle);
 
-		if (JOB_BOOTCACHE_HACK_CHECK(j)) {
-			did_first_per_user_launchd_BootCache_hack = true;
-		}
-
 		if (likely(!j->legacy_mach_job)) {
 			job_assumes(j, runtime_close(oepair[1]) != -1);
 		}
@@ -3543,23 +3541,6 @@
 }
 
 void
-do_first_per_user_launchd_hack(void)
-{
-	char *bcct_tool[] = { "/usr/sbin/BootCacheControl", "tag", NULL };
-	int dummystatus;
-	pid_t bcp;
-
-	if (launchd_assumes((bcp = vfork()) != -1)) {
-		if (bcp == 0) {
-			execve(bcct_tool[0], bcct_tool, environ);
-			_exit(EXIT_FAILURE);
-		} else {
-			launchd_assumes(waitpid(bcp, &dummystatus, 0) != -1);
-		}
-	}
-}
-
-void
 job_start_child(job_t j)
 {
 	typeof(posix_spawn) *psf;
@@ -3572,10 +3553,6 @@
 	size_t binpref_out_cnt = 0;
 	size_t i;
 
-	if (JOB_BOOTCACHE_HACK_CHECK(j)) {
-		do_first_per_user_launchd_hack();
-	}
-
 	job_assumes(j, posix_spawnattr_init(&spattr) == 0);
 
 	job_setup_attributes(j);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/launchd-changes/attachments/20090212/16bee9c4/attachment-0001.html>


More information about the launchd-changes mailing list