加入该功能后当系统首次启动会创建/data/zygote.blcr文件,由于需要checkpoint,导致比正常启动时间慢较多。后续只要该文件存在,系统就会跨过类加载过程,进而加快启动速度。
4 测试验证
下表列出了虚拟机加入blcr前和blcr后的10次的启动速度。
Emulator启动参数如下:
emulator.exe -kernel zImage -show-kernel -partition-size 200 -memory 200 -skindir ./skins -skin WQVGA432 -shell -sysdir ./ -data userdata.img -ramdisk ramdisk.img -system system.img -sdcard sdcard.img -sdcard sdcard.img
模式
启动时间(单位:秒)
采用blcr
42
43
42
36
42
41
42
38
39
43
正常启动
64
63
50
57
65
54
52
45
53
49
启用blcr后平均启动时间为41,相比正常启动平均时间55秒快了14秒。启动时间的改善是明显的。
附部分android.mk文件
cat ./libcr/Android.mk
# Copyright 2006 The Android Open Source Project
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SHARED_LIBRARIES += libc
lib_SOURCES = \
cr_omit.c
LOCAL_SRC_FILES:= $(lib_SOURCES)
LOCAL_C_INCLUDES := \
$(KERNEL_HEADERS) \
$(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/arch/arm/
LOCAL_CFLAGS := -DHAVE_CONFIG_H -DSHUAIWEN
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libcr_omit
include $(BUILD_SHARED_LIBRARY)
#libcr_run.so
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SHARED_LIBRARIES += libc
lib_SOURCES = \
cr_run.c
LOCAL_SRC_FILES:= $(lib_SOURCES)
LOCAL_C_INCLUDES := \
$(KERNEL_HEADERS) \
$(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/arch/arm/
LOCAL_CFLAGS := -DHAVE_CONFIG_H -DSHUAIWEN
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libcr_run
include $(BUILD_SHARED_LIBRARY)
#libcr
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SHARED_LIBRARIES += libc
lib_SOURCES = \
cr_async.c.arm \
cr_trace.c \
cr_core.c.arm \
cr_sig_sync.c.arm \
cr_cs.c.arm \
cr_pthread.c \
cr_strerror.c \
cr_request.c \
cr_syscall.c.arm \
cr_omit.c \
cr_run.c
LOCAL_SRC_FILES:= $(lib_SOURCES)
LOCAL_C_INCLUDES := \
$(KERNEL_HEADERS) \
$(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/arch/arm/
LOCAL_CFLAGS := -DHAVE_CONFIG_H -DSHUAIWEN -g
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libcr
include $(BUILD_SHARED_LIBRARY)
cat ./util/cr_restart/Android.mk
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SHARED_LIBRARIES += libc
LOCAL_SHARED_LIBRARIES += libcr_run
LOCAL_SHARED_LIBRARIES += libcr
LOCAL_SRC_FILES:=cr_restart.c
LOCAL_C_INCLUDES := \
$(KERNEL_HEADERS) \
$(LOCAL_PATH)/../../include \
$(LOCAL_PATH)/arch/arm/
LOCAL_MODULE := cr_restart
include $(BUILD_EXECUTABLE)
cat ./util/cr_restart/Android.mk
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SHARED_LIBRARIES += libc
LOCAL_SHARED_LIBRARIES += libcr_run
LOCAL_SHARED_LIBRARIES += libcr
LOCAL_SRC_FILES:=cr_restart.c
LOCAL_C_INCLUDES := \
$(KERNEL_HEADERS) \
$(LOCAL_PATH)/../../include \
$(LOCAL_PATH)/arch/arm/
LOCAL_MODULE := cr_restart
include $(BUILD_EXECUTABLE)
[root@wen blcr-0.8.2]#
[root@wen blcr-0.8.2]#
[root@wen blcr-0.8.2]# cat ./util/cr_checkpoint/Android.mk
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SHARED_LIBRARIES += libc
LOCAL_SHARED_LIBRARIES += libcr_run
LOCAL_SHARED_LIBRARIES += libcr
LOCAL_SRC_FILES:=cr_checkpoint.c
LOCAL_C_INCLUDES := \
$(KERNEL_HEADERS) \
$(LOCAL_PATH)/../../include \
$(LOCAL_PATH)/arch/arm/
LOCAL_MODULE := cr_checkpoint
include $(BUILD_EXECUTABLE)
下面是crut_util_libcr.c,放到上面同一个目录下面。你也可以自己从blcr中复制出来。
/*
* Berkeley Lab Checkpoint/Restart (BLCR) for Linux is Copyright (c)
* 2008, The Regents of the University of California, through Lawrence
* Berkeley National Laboratory (subject to receipt of any required
* approvals from the U.S. Dept. of Energy). All rights reserved.
*
* Portions may be copyrighted by others, as may be noted in specific
* copyright notices within specific files.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: crut_util_libcr.c,v 1.5 2008/12/26 10:50:35 phargrov Exp $
*
* Utility functions for BLCR tests (libcr-dependent portions)
*/
#define _LARGEFILE64_SOURCE 1 /* For O_LARGEFILE */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "crut_util.h"
/* checkpoint request/poll wrappers for simpler code */
int
crut_checkpoint_request(cr_checkpoint_handle_t *handle_p, const char *filename) {
int rc;
cr_checkpoint_args_t my_args;
if (filename) {
/* remove existing context file, if any */
(void)unlink(filename);
/* open the context file */
rc = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0600);
} else {
/* NULL -> /dev/null */
rc = open("/dev/null", O_WRONLY | O_LARGEFILE);
}
if (rc < 0) {
perror("open");
return rc;
}
cr_initialize_checkpoint_args_t(&my_args);
my_args.cr_fd = rc; /* still holds the return from open() */
my_args.cr_scope = CR_SCOPE_PROC;
/* issue the request */
rc = cr_request_checkpoint(&my_args, handle_p);
if (rc < 0) {
(void)close(my_args.cr_fd);
if (filename) (void)unlink(filename);
perror("cr_request_checkpoint");
return rc;
}
return my_args.cr_fd;
}
int
crut_checkpoint_wait(cr_checkpoint_handle_t *handle_p, int fd) {
int rc, save_err;
do {
rc = cr_poll_checkpoint(handle_p, NULL);
if (rc < 0) {
if ((rc == CR_POLL_CHKPT_ERR_POST) && (errno == CR_ERESTARTED)) {
/* restarting -- not an error */
rc = 1; /* Signify RESTART to caller */
} else if (errno == EINTR) {
/* poll was interrupted by a signal -- retry */
continue;
} else {
/* return the error to caller */
break;
}
} else if (rc == 0) {
fprintf(stderr, "cr_poll_checkpoint returned unexpected 0\n");
rc = -1;
goto out;
} else {
rc = 0; /* Signify CONTINUE to caller */
}
} while (rc < 0);
save_err = errno;
#if 0 // Nothing in the testsuite needs this, but your APP might want it.
(void)fsync(fd);
#endif
(void)close(fd);
errno = save_err;
out:
return rc;
}
int
crut_checkpoint_block(const char *filename) {
cr_checkpoint_handle_t my_handle;
int ret, fd, save_err;
fd = crut_checkpoint_request(&my_handle, filename);
if (fd < 0) return fd;
ret = crut_checkpoint_wait(&my_handle, fd);
save_err = errno;
(void)close(fd);
errno = save_err;
return ret;
}