[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