Some initial work towards cutting down the number of fork calls we do

This commit is contained in:
ridiculousfish 2012-03-06 15:12:37 -08:00
parent 9ee4e4e05c
commit 36fe1e4a46
5 changed files with 21 additions and 3 deletions

View file

@ -1952,6 +1952,7 @@ void set_main_thread() {
/* Notice when we've forked */ /* Notice when we've forked */
static pid_t initial_pid; static pid_t initial_pid;
bool is_forked_child(void) { bool is_forked_child(void) {
bool is_child_of_fork = (getpid() != initial_pid); bool is_child_of_fork = (getpid() != initial_pid);
if (is_child_of_fork) { if (is_child_of_fork) {

View file

@ -1237,6 +1237,8 @@ void exec( parser_t &parser, job_t *j )
std::string actual_cmd_str = wcs2string(p->actual_cmd); std::string actual_cmd_str = wcs2string(p->actual_cmd);
const char *actual_cmd = actual_cmd_str.c_str(); const char *actual_cmd = actual_cmd_str.c_str();
const wchar_t *reader_current_filename();
printf("forking for '%s' in '%ls'\n", actual_cmd, reader_current_filename());
pid = execute_fork(true /* must drain threads */); pid = execute_fork(true /* must drain threads */);
if( pid == 0 ) if( pid == 0 )
{ {

View file

@ -89,7 +89,7 @@ static int read_init()
{ {
wcstring config_dir_escaped = escape_string( config_dir, 1 ); wcstring config_dir_escaped = escape_string( config_dir, 1 );
wcstring eval_buff = format_string(L"builtin . %ls/config.fish 2>/dev/null", config_dir_escaped.c_str()); wcstring eval_buff = format_string(L"builtin . %ls/config.fish 2>/dev/null", config_dir_escaped.c_str());
parser.eval( eval_buff.c_str(), 0, TOP ); parser.eval( eval_buff, 0, TOP );
} }
return 1; return 1;
@ -265,6 +265,7 @@ static int fish_parse_opt( int argc, char **argv, const char **cmd_ptr )
parses commands from stdin or files, depending on arguments parses commands from stdin or files, depending on arguments
*/ */
extern int g_fork_count;
int main( int argc, char **argv ) int main( int argc, char **argv )
{ {
struct stat tmp; struct stat tmp;
@ -304,6 +305,8 @@ int main( int argc, char **argv )
parser_t &parser = parser_t::principal_parser(); parser_t &parser = parser_t::principal_parser();
printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);
if( read_init() ) if( read_init() )
{ {
if( cmd != 0 ) if( cmd != 0 )
@ -387,5 +390,7 @@ int main( int argc, char **argv )
env_destroy(); env_destroy();
printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);
return res?STATUS_UNKNOWN_COMMAND:proc_get_last_status(); return res?STATUS_UNKNOWN_COMMAND:proc_get_last_status();
} }

View file

@ -200,7 +200,13 @@ void iothread_service_completion(void) {
void iothread_drain_all(void) { void iothread_drain_all(void) {
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
ASSERT_IS_NOT_FORKED_CHILD(); ASSERT_IS_NOT_FORKED_CHILD();
if (s_active_thread_count == 0)
return;
int thread_count = s_active_thread_count;
double now = timef();
while (s_active_thread_count > 0) { while (s_active_thread_count > 0) {
iothread_service_completion(); iothread_service_completion();
} }
double after = timef();
printf("(Waited %.02f msec for %d thread(s) to drain)\n", 1000 * (after - now), thread_count);
} }

View file

@ -304,6 +304,8 @@ int setup_child_process( job_t *j, process_t *p )
} }
int g_fork_count = 0;
/** /**
This function is a wrapper around fork. If the fork calls fails This function is a wrapper around fork. If the fork calls fails
with EAGAIN, it is retried FORK_LAPS times, with a very slight with EAGAIN, it is retried FORK_LAPS times, with a very slight
@ -323,6 +325,8 @@ pid_t execute_fork(bool wait_for_threads_to_die)
struct timespec pollint; struct timespec pollint;
int i; int i;
g_fork_count++;
for( i=0; i<FORK_LAPS; i++ ) for( i=0; i<FORK_LAPS; i++ )
{ {
pid = fork(); pid = fork();