4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
30 * Deal with the parallel processing
36 #include <errno.h> /* errno */
39 #include <mksh/dosys.h> /* redirect_io() */
40 #include <mksh/macro.h> /* expand_value() */
41 #include <mksh/misc.h> /* getmem() */
42 #include <sys/signal.h>
44 #include <sys/types.h>
45 #include <sys/utsname.h>
59 * This const should be in avo_dms/include/AvoDmakeCommand.h
61 const int local_host_mask
= 0x20;
72 static Boolean just_did_subtree
= false;
73 static char local_host
[MAXNAMELEN
] = "";
74 static char user_name
[MAXNAMELEN
] = "";
75 static int pmake_max_jobs
= 0;
76 static pid_t process_running
= -1;
77 static Running
*running_tail
= &running_list
;
78 static Name subtree_conflict
;
79 static Name subtree_conflict2
;
83 * File table of contents
85 static void delete_running_struct(Running rp
);
86 static Boolean
dependency_conflict(Name target
);
87 static Doname
distribute_process(char **commands
, Property line
);
88 static void doname_subtree(Name target
, Boolean do_get
, Boolean implicit
);
89 static void dump_out_file(char *filename
, Boolean err
);
90 static void finish_doname(Running rp
);
91 static void maybe_reread_make_state(void);
92 static void process_next(void);
93 static void reset_conditionals(int cnt
, Name
*targets
, Property
*locals
);
94 static pid_t
run_rule_commands(char *host
, char **commands
);
95 static Property
*set_conditionals(int cnt
, Name
*targets
);
96 static void store_conditionals(Running rp
);
100 * execute_parallel(line, waitflg)
103 * parallel mode: spawns a parallel process to execute the command group.
106 * The result of the execution
109 * line The command group to execute
112 execute_parallel(Property line
, Boolean waitflg
, Boolean local
)
116 char *commands
[MAXRULES
+ 5];
121 Name make_machines_name
;
124 Doname result
= build_ok
;
127 Name target
= line
->body
.line
.target
;
128 Boolean wrote_state_file
= false;
130 if ((pmake_max_jobs
== 0) &&
131 (dmake_mode_type
== parallel_mode
)) {
132 if (local_host
[0] == '\0') {
133 (void) gethostname(local_host
, MAXNAMELEN
);
135 MBSTOWCS(wcs_buffer
, "DMAKE_MAX_JOBS");
136 dmake_name
= GETNAME(wcs_buffer
, FIND_LENGTH
);
137 if (((prop
= get_prop(dmake_name
->prop
, macro_prop
)) != NULL
) &&
138 ((dmake_value
= prop
->body
.macro
.value
) != NULL
)) {
139 pmake_max_jobs
= atoi(dmake_value
->string_mb
);
140 if (pmake_max_jobs
<= 0) {
141 warning(gettext("DMAKE_MAX_JOBS cannot be less than or equal to zero."));
142 warning(gettext("setting DMAKE_MAX_JOBS to %d."), PMAKE_DEF_MAX_JOBS
);
143 pmake_max_jobs
= PMAKE_DEF_MAX_JOBS
;
147 * For backwards compatibility w/ PMake 1.x, when
148 * DMake 2.x is being run in parallel mode, DMake
149 * should parse the PMake startup file
150 * $(HOME)/.make.machines to get the pmake_max_jobs.
152 MBSTOWCS(wcs_buffer
, "PMAKE_MACHINESFILE");
153 dmake_name
= GETNAME(wcs_buffer
, FIND_LENGTH
);
154 if (((prop
= get_prop(dmake_name
->prop
, macro_prop
)) != NULL
) &&
155 ((dmake_value
= prop
->body
.macro
.value
) != NULL
)) {
156 make_machines_name
= dmake_value
;
158 make_machines_name
= NULL
;
160 if ((pmake_max_jobs
= read_make_machines(make_machines_name
)) <= 0) {
161 pmake_max_jobs
= PMAKE_DEF_MAX_JOBS
;
166 if ((dmake_mode_type
== serial_mode
) ||
167 ((dmake_mode_type
== parallel_mode
) && (waitflg
))) {
168 return (execute_serial(line
));
176 for (rule
= line
->body
.line
.command_used
;
179 if (posix
&& (touch
|| quest
) && !rule
->always_exec
) {
184 vpath_translation(rule
->command_line
);
190 if (rule
->command_line
->hash
.length
> 0) {
191 if (++argcnt
== MAXRULES
) {
195 if (rule
->silent
&& !silent
) {
198 if (rule
->ignore_error
) {
201 /* XXX - need to add support for + prefix */
202 if (silent_flag
|| ignore
) {
203 *p
= getmem((silent_flag
? 1 : 0) +
211 *cp
++ = (int) at_char
;
214 *cp
++ = (int) hyphen_char
;
216 (void) strcpy(cp
, rule
->command_line
->string_mb
);
218 *p
++ = rule
->command_line
->string_mb
;
224 (report_dependencies_level
> 0)) {
230 Doname res
= distribute_process(commands
, line
);
231 if (res
== build_running
) {
232 parallel_process_cnt
++;
236 * Return only those memory that were specially allocated
237 * for part of commands.
239 for (int i
= 0; commands
[i
] != NULL
; i
++) {
240 if ((commands
[i
][0] == (int) at_char
) ||
241 (commands
[i
][0] == (int) hyphen_char
)) {
242 retmem_mb(commands
[i
]);
251 #include <unistd.h> /* sysconf(_SC_NPROCESSORS_ONLN) */
252 #include <sys/ipc.h> /* ftok() */
253 #include <sys/shm.h> /* shmget(), shmat(), shmdt(), shmctl() */
254 #include <semaphore.h> /* sem_init(), sem_trywait(), sem_post(), sem_destroy() */
255 #include <sys/loadavg.h> /* getloadavg() */
258 * adjust_pmake_max_jobs (int pmake_max_jobs)
261 * pmake_max_jobs - max jobs limit set by user
263 * External functions used:
268 adjust_pmake_max_jobs (int pmake_max_jobs
)
273 int adjusted_max_jobs
;
276 if ((ncpu
= sysconf(_SC_NPROCESSORS_ONLN
)) <= 0) {
280 if (getloadavg(loadavg
, 3) != 3) return(pmake_max_jobs
);
281 adjustment
= ((int)loadavg
[LOADAVG_1MIN
]);
282 if (adjustment
< 2) return(pmake_max_jobs
);
284 adjustment
= adjustment
/ ncpu
;
286 adjusted_max_jobs
= pmake_max_jobs
- adjustment
;
287 if (adjusted_max_jobs
< 1) adjusted_max_jobs
= 1;
288 return(adjusted_max_jobs
);
292 * M2 adjust mode data and functions
294 * m2_init() - initializes M2 shared semaphore
295 * m2_acquire_job() - decrements M2 semaphore counter
296 * m2_release_job() - increments M2 semaphore counter
297 * m2_fini() - destroys M2 semaphore and shared memory*
299 * Environment variables:
302 * External functions:
303 * ftok(), shmget(), shmat(), shmdt(), shmctl()
304 * sem_init(), sem_trywait(), sem_post(), sem_destroy()
305 * creat(), close(), unlink()
309 * m2_file - tmp file name to create ipc key for shared memory
310 * m2_shm_id - shared memory id
311 * m2_shm_sem - shared memory semaphore
314 static char m2_file
[MAXPATHLEN
];
315 static int m2_shm_id
= -1;
316 static sem_t
* m2_shm_sem
= 0;
323 if ((var
= getenv("__DMAKE_M2_FILE__")) == 0) {
324 /* compose tmp file name */
325 sprintf(m2_file
, "%s/dmake.m2.%d.XXXXXX", tmpdir
, getpid());
327 /* create tmp file */
328 int fd
= mkstemp(m2_file
);
335 /* using existing semaphore */
336 strcpy(m2_file
, var
);
339 /* combine IPC key */
340 if ((key
= ftok(m2_file
, 38)) == (key_t
) -1) {
344 /* create shared memory */
345 if ((m2_shm_id
= shmget(key
, sizeof(*m2_shm_sem
), 0666 | (var
? 0 : IPC_CREAT
|IPC_EXCL
))) == -1) {
349 /* attach shared memory */
350 if ((m2_shm_sem
= (sem_t
*) shmat(m2_shm_id
, 0, 0666)) == (sem_t
*)-1) {
356 /* initialize semaphore */
357 if (sem_init(m2_shm_sem
, 1, pmake_max_jobs
)) {
361 /* alloc memory for env variable */
362 if ((var
= (char*) malloc(MAXPATHLEN
)) == 0) {
367 sprintf(var
, "__DMAKE_M2_FILE__=%s", m2_file
);
377 if (m2_shm_id
>= 0) {
378 struct shmid_ds stat
;
380 /* determine the number of attached processes */
381 if (shmctl(m2_shm_id
, IPC_STAT
, &stat
) == 0) {
382 if (stat
.shm_nattch
<= 1) {
383 /* destroy semaphore */
384 if (m2_shm_sem
!= 0) {
385 (void) sem_destroy(m2_shm_sem
);
388 /* destroy shared memory */
389 (void) shmctl(m2_shm_id
, IPC_RMID
, &stat
);
391 /* remove tmp file created for the key */
392 (void) unlink(m2_file
);
394 /* detach shared memory */
395 if (m2_shm_sem
!= 0) {
396 (void) shmdt((char*) m2_shm_sem
);
408 if ((m2_shm_id
>= 0) && (m2_shm_sem
!= 0)) {
409 if (sem_trywait(m2_shm_sem
) == 0) {
412 if (errno
== EAGAIN
) {
421 if ((m2_shm_id
>= 0) && (m2_shm_sem
!= 0)) {
422 if (sem_post(m2_shm_sem
) == 0) {
433 * ADJUST_M1 - adjustment by system load (default)
434 * ADJUST_M2 - fixed limit of jobs for the group of nested dmakes
435 * ADJUST_NONE - no adjustment - fixed limit of jobs for the current dmake
442 } job_adjust_mode
= ADJUST_UNKNOWN
;
445 * void job_adjust_fini()
448 * Cleans up job adjust data.
451 * job_adjust_mode Current job adjust mode
455 if (job_adjust_mode
== ADJUST_M2
) {
461 * void job_adjust_error()
464 * Prints warning message, cleans up job adjust data, and disables job adjustment
467 * DMAKE_ADJUST_MAX_JOBS
469 * External functions:
473 * job_adjust_mode Current job adjust mode
477 if (job_adjust_mode
!= ADJUST_NONE
) {
478 /* cleanup internals */
481 /* warning message for the user */
482 warning(gettext("Encountered max jobs auto adjustment error - disabling auto adjustment."));
484 /* switch off job adjustment for the children */
485 putenv(strdup("DMAKE_ADJUST_MAX_JOBS=NO"));
487 /* and for this dmake */
488 job_adjust_mode
= ADJUST_NONE
;
493 * void job_adjust_init()
496 * Parses DMAKE_ADJUST_MAX_JOBS env variable
497 * and performs appropriate initializations.
500 * DMAKE_ADJUST_MAX_JOBS
501 * DMAKE_ADJUST_MAX_JOBS == "NO" - no adjustment
502 * DMAKE_ADJUST_MAX_JOBS == "M2" - M2 adjust mode
503 * other - M1 adjust mode
505 * External functions:
509 * job_adjust_mode Current job adjust mode
513 if (job_adjust_mode
== ADJUST_UNKNOWN
) {
515 job_adjust_mode
= ADJUST_M1
;
517 /* determine adjust mode */
518 if (char *var
= getenv("DMAKE_ADJUST_MAX_JOBS")) {
519 if (strcasecmp(var
, "NO") == 0) {
520 job_adjust_mode
= ADJUST_NONE
;
521 } else if (strcasecmp(var
, "M2") == 0) {
522 job_adjust_mode
= ADJUST_M2
;
526 /* M2 specific initialization */
527 if (job_adjust_mode
== ADJUST_M2
) {
537 * distribute_process(char **commands, Property line)
540 * commands argv vector of commands to execute
543 * The result of the execution
545 * Static variables used:
546 * process_running Set to the pid of the process set running
547 * job_adjust_mode Current job adjust mode
550 distribute_process(char **commands
, Property line
)
552 static unsigned file_number
= 0;
553 wchar_t string
[MAXPATHLEN
];
554 char mbstring
[MAXPATHLEN
];
558 char *tmp_index_str_ptr
;
560 /* initialize adjust mode, if not initialized */
561 if (job_adjust_mode
== ADJUST_UNKNOWN
) {
565 /* actions depend on adjust mode */
566 switch (job_adjust_mode
) {
568 while (parallel_process_cnt
>= adjust_pmake_max_jobs (pmake_max_jobs
)) {
569 await_parallel(false);
570 finish_children(true);
574 if ((res
= m2_acquire_job()) == 0) {
575 if (parallel_process_cnt
> 0) {
576 await_parallel(false);
577 finish_children(true);
579 if ((res
= m2_acquire_job()) == 0) {
587 /* job adjustment error */
591 while (parallel_process_cnt
>= pmake_max_jobs
) {
592 await_parallel(false);
593 finish_children(true);
598 while (parallel_process_cnt
>= pmake_max_jobs
) {
599 await_parallel(false);
600 finish_children(true);
606 * Tell the user what DMake is doing.
608 if (!silent
&& output_mode
!= txt2_mode
) {
610 * Print local_host --> x job(s).
612 (void) fprintf(stdout
,
613 gettext("%s --> %d %s\n"),
615 parallel_process_cnt
+ 1,
616 (parallel_process_cnt
== 0) ? gettext("job") : gettext("jobs"));
618 /* Print command line(s). */
620 while (commands
[tmp_index
] != NULL
) {
622 /* XXX - need to add [2] when + prefix is added */
623 if ((commands
[tmp_index
][0] != (int) at_char
) &&
624 (commands
[tmp_index
][1] != (int) at_char
)) {
625 tmp_index_str_ptr
= commands
[tmp_index
];
626 if (*tmp_index_str_ptr
== (int) hyphen_char
) {
629 (void) fprintf(stdout
, "%s\n", tmp_index_str_ptr
);
633 (void) fflush(stdout
);
636 (void) sprintf(mbstring
,
637 "%s/dmake.stdout.%d.%d.XXXXXX",
644 stdout_file
= strdup(mbstring
);
648 (void) sprintf(mbstring
,
649 "%s/dmake.stderr.%d.%d.XXXXXX",
656 stderr_file
= strdup(mbstring
);
659 process_running
= run_rule_commands(local_host
, commands
);
661 return build_running
;
665 * doname_parallel(target, do_get, implicit)
667 * Processes the given target and finishes up any parallel
668 * processes left running.
671 * Result of target build
674 * target Target to build
675 * do_get True if sccs get to be done
676 * implicit True if this is an implicit target
679 doname_parallel(Name target
, Boolean do_get
, Boolean implicit
)
683 result
= doname_check(target
, do_get
, implicit
, false);
684 if (result
== build_ok
|| result
== build_failed
) {
688 return (Doname
) target
->state
;
692 * doname_subtree(target, do_get, implicit)
694 * Completely computes an object and its dependents for a
695 * serial subtree build.
698 * target Target to build
699 * do_get True if sccs get to be done
700 * implicit True if this is an implicit target
702 * Static variables used:
703 * running_tail Tail of the list of running processes
705 * Global variables used:
706 * running_list The list of running processes
709 doname_subtree(Name target
, Boolean do_get
, Boolean implicit
)
711 Running save_running_list
;
712 Running
*save_running_tail
;
714 save_running_list
= running_list
;
715 save_running_tail
= running_tail
;
717 running_tail
= &running_list
;
718 target
->state
= build_subtree
;
719 target
->checking_subtree
= true;
720 while(doname_check(target
, do_get
, implicit
, false) == build_running
) {
721 target
->checking_subtree
= false;
723 target
->state
= build_subtree
;
725 target
->checking_subtree
= false;
726 running_list
= save_running_list
;
727 running_tail
= save_running_tail
;
733 * Keeps processing until the running_list is emptied out.
737 * Global variables used:
738 * running_list The list of running processes
743 while (running_list
!= NULL
) {
745 await_parallel(false);
746 finish_children(true);
748 if (running_list
!= NULL
) {
757 * Searches the running list for any targets which can start processing.
758 * This can be a pending target, a serial target, or a subtree target.
762 * Static variables used:
763 * running_tail The end of the list of running procs
764 * subtree_conflict A target which conflicts with a subtree
765 * subtree_conflict2 The other target which conflicts
767 * Global variables used:
768 * commands_done True if commands executed
769 * debug_level Controls debug output
770 * parallel_process_cnt Number of parallel process running
771 * recursion_level Indentation for debug output
772 * running_list List of running processes
782 Boolean quiescent
= true;
783 Running
*subtree_target
;
784 Boolean saved_commands_done
;
785 Property
*conditionals
;
787 subtree_target
= NULL
;
788 subtree_conflict
= NULL
;
789 subtree_conflict2
= NULL
;
791 * If nothing currently running, build a serial target, if any.
794 for (rp_prev
= &running_list
, rp
= running_list
;
795 rp
!= NULL
&& parallel_process_cnt
== 0;
797 if (rp
->state
== build_serial
) {
799 if (rp
->next
== NULL
) {
800 running_tail
= rp_prev
;
802 recursion_level
= rp
->recursion_level
;
803 rp
->target
->state
= build_pending
;
804 (void) doname_check(rp
->target
,
809 delete_running_struct(rp
);
816 * Find a target to build. The target must be pending, have all
817 * its dependencies built, and not be in a target group with a target
818 * currently building.
821 for (rp_prev
= &running_list
, rp
= running_list
;
824 if (!(rp
->state
== build_pending
||
825 rp
->state
== build_subtree
)) {
828 } else if (rp
->state
== build_pending
) {
829 line
= get_prop(rp
->target
->prop
, line_prop
);
830 for (dep
= line
->body
.line
.dependencies
;
833 if (dep
->name
->state
== build_running
||
834 dep
->name
->state
== build_pending
||
835 dep
->name
->state
== build_serial
) {
840 for (target_group
= line
->body
.line
.target_group
;
841 target_group
!= NULL
;
842 target_group
= target_group
->next
) {
843 if (is_running(target_group
->name
)) {
847 if (target_group
== NULL
) {
849 if (rp
->next
== NULL
) {
850 running_tail
= rp_prev
;
852 recursion_level
= rp
->recursion_level
;
853 rp
->target
->state
= rp
->redo
?
854 build_dont_know
: build_pending
;
855 saved_commands_done
= commands_done
;
858 (rp
->conditional_cnt
,
859 rp
->conditional_targets
);
860 rp
->target
->dont_activate_cond_values
= true;
861 if ((doname_check(rp
->target
,
864 rp
->target
->has_target_prop
? true : false) !=
870 rp
->target
->dont_activate_cond_values
= false;
872 (rp
->conditional_cnt
,
873 rp
->conditional_targets
,
876 delete_running_struct(rp
);
889 * If nothing has been found to build and there exists a subtree
890 * target with no dependency conflicts, build it.
894 for (rp_prev
= &running_list
, rp
= running_list
;
897 if (rp
->state
== build_subtree
) {
898 if (!dependency_conflict(rp
->target
)) {
900 if (rp
->next
== NULL
) {
901 running_tail
= rp_prev
;
903 recursion_level
= rp
->recursion_level
;
904 doname_subtree(rp
->target
,
908 delete_running_struct(rp
);
911 subtree_target
= rp_prev
;
920 * If still nothing found to build, we either have a deadlock
921 * or a subtree with a dependency conflict with something waiting
925 if (subtree_target
== NULL
) {
926 fatal(gettext("Internal error: deadlock detected in process_next"));
928 rp
= *subtree_target
;
929 if (debug_level
> 0) {
930 warning(gettext("Conditional macro conflict encountered for %s between %s and %s"),
931 subtree_conflict2
->string_mb
,
932 rp
->target
->string_mb
,
933 subtree_conflict
->string_mb
);
935 *subtree_target
= (*subtree_target
)->next
;
936 if (rp
->next
== NULL
) {
937 running_tail
= subtree_target
;
939 recursion_level
= rp
->recursion_level
;
940 doname_subtree(rp
->target
, rp
->do_get
, rp
->implicit
);
941 delete_running_struct(rp
);
947 * set_conditionals(cnt, targets)
949 * Sets the conditional macros for the targets given in the array of
950 * targets. The old macro values are returned in an array of
951 * Properties for later resetting.
954 * Array of conditional macro settings
957 * cnt Number of targets
958 * targets Array of targets
961 set_conditionals(int cnt
, Name
*targets
)
963 Property
*locals
, *lp
;
966 locals
= (Property
*) getmem(cnt
* sizeof(Property
));
967 for (lp
= locals
, tp
= targets
;
970 *lp
= (Property
) getmem((*tp
)->conditional_cnt
*
971 sizeof(struct _Property
));
972 set_locals(*tp
, *lp
);
978 * reset_conditionals(cnt, targets, locals)
980 * Resets the conditional macros as saved in the given array of
981 * Properties. The resets are done in reverse order. Afterwards the
982 * data structures are freed.
985 * cnt Number of targets
986 * targets Array of targets
987 * locals Array of dependency macro settings
990 reset_conditionals(int cnt
, Name
*targets
, Property
*locals
)
995 for (tp
= targets
+ (cnt
- 1), lp
= locals
+ (cnt
- 1);
1000 get_prop((*tp
)->prop
, conditional_prop
),
1002 retmem_mb((caddr_t
) *lp
);
1004 retmem_mb((caddr_t
) locals
);
1008 * dependency_conflict(target)
1010 * Returns true if there is an intersection between
1011 * the subtree of the target and any dependents of the pending targets.
1014 * True if conflict found
1017 * target Subtree target to check
1019 * Static variables used:
1020 * subtree_conflict Target conflict found
1021 * subtree_conflict2 Second conflict found
1023 * Global variables used:
1024 * running_list List of running processes
1025 * wait_name .WAIT, not a real dependency
1028 dependency_conflict(Name target
)
1031 Property pending_line
;
1033 Dependency pending_dp
;
1036 /* Return if we are already checking this target */
1037 if (target
->checking_subtree
) {
1040 target
->checking_subtree
= true;
1041 line
= get_prop(target
->prop
, line_prop
);
1043 target
->checking_subtree
= false;
1046 /* Check each dependency of the target for conflicts */
1047 for (dp
= line
->body
.line
.dependencies
; dp
!= NULL
; dp
= dp
->next
) {
1048 /* Ignore .WAIT dependency */
1049 if (dp
->name
== wait_name
) {
1053 * For each pending target, look for a dependency which
1054 * is the same as a dependency of the subtree target. Since
1055 * we can't build the subtree until all pending targets have
1056 * finished which depend on the same dependency, this is
1059 for (rp
= running_list
; rp
!= NULL
; rp
= rp
->next
) {
1060 if (rp
->state
== build_pending
) {
1061 pending_line
= get_prop(rp
->target
->prop
,
1063 if (pending_line
== NULL
) {
1066 for(pending_dp
= pending_line
->
1067 body
.line
.dependencies
;
1069 pending_dp
= pending_dp
->next
) {
1070 if (dp
->name
== pending_dp
->name
) {
1071 target
->checking_subtree
1073 subtree_conflict
= rp
->target
;
1074 subtree_conflict2
= dp
->name
;
1080 if (dependency_conflict(dp
->name
)) {
1081 target
->checking_subtree
= false;
1085 target
->checking_subtree
= false;
1090 * await_parallel(waitflg)
1092 * Waits for parallel children to exit and finishes their processing.
1093 * If waitflg is false, the function returns after update_delay.
1099 await_parallel(Boolean waitflg
)
1110 (void) alarm((int) update_delay
);
1112 pid
= waitpid((pid_t
)-1,
1114 nohang
? WNOHANG
: 0);
1120 if (waiterr
== EINTR
) {
1130 for (rp
= running_list
;
1131 (rp
!= NULL
) && (rp
->pid
!= pid
);
1136 fatal(gettext("Internal error: returned child pid not in running_list"));
1138 rp
->state
= (WIFEXITED(status
) && WEXITSTATUS(status
) == 0) ? build_ok
: build_failed
;
1141 parallel_process_cnt
--;
1143 if (job_adjust_mode
== ADJUST_M2
) {
1144 if (m2_release_job()) {
1152 * finish_children(docheck)
1154 * Finishes the processing for all targets which were running
1155 * and have now completed.
1158 * docheck Completely check the finished target
1160 * Static variables used:
1161 * running_tail The tail of the running list
1163 * Global variables used:
1164 * continue_after_error -k flag
1165 * fatal_in_progress True if we are finishing up after fatal err
1166 * running_list List of running processes
1169 finish_children(Boolean docheck
)
1174 struct stat out_buf
;
1178 Boolean silent_flag
;
1180 for (rp_prev
= &running_list
, rp
= running_list
;
1183 bypass_for_loop_inc_4
:
1185 * If the state is ok or failed, then this target has
1186 * finished building.
1187 * In parallel_mode, output the accumulated stdout/stderr.
1188 * Read the auto dependency stuff, handle a failed build,
1189 * update the target, then finish the doname process for
1192 if (rp
->state
== build_ok
|| rp
->state
== build_failed
) {
1193 *rp_prev
= rp
->next
;
1194 if (rp
->next
== NULL
) {
1195 running_tail
= rp_prev
;
1197 if ((line2
= rp
->command
) == NULL
) {
1198 line2
= get_prop(rp
->target
->prop
, line_prop
);
1203 * Check if there were any job output
1204 * from the parallel build.
1206 if (rp
->stdout_file
!= NULL
) {
1207 if (stat(rp
->stdout_file
, &out_buf
) < 0) {
1208 fatal(gettext("stat of %s failed: %s"),
1213 if ((line2
!= NULL
) &&
1214 (out_buf
.st_size
> 0)) {
1216 for (rule
= line2
->body
.line
.command_used
,
1217 silent_flag
= silent
;
1219 rule
= rule
->next
) {
1220 cmds_length
+= rule
->command_line
->hash
.length
+ 1;
1221 silent_flag
= BOOLEAN(silent_flag
|| rule
->silent
);
1223 if (out_buf
.st_size
!= cmds_length
|| silent_flag
||
1224 output_mode
== txt2_mode
) {
1225 dump_out_file(rp
->stdout_file
, false);
1228 (void) unlink(rp
->stdout_file
);
1229 retmem_mb(rp
->stdout_file
);
1230 rp
->stdout_file
= NULL
;
1233 if (!out_err_same
&& (rp
->stderr_file
!= NULL
)) {
1234 if (stat(rp
->stderr_file
, &out_buf
) < 0) {
1235 fatal(gettext("stat of %s failed: %s"),
1239 if ((line2
!= NULL
) &&
1240 (out_buf
.st_size
> 0)) {
1241 dump_out_file(rp
->stderr_file
, true);
1243 (void) unlink(rp
->stderr_file
);
1244 retmem_mb(rp
->stderr_file
);
1245 rp
->stderr_file
= NULL
;
1248 check_state(rp
->temp_file
);
1249 if (rp
->temp_file
!= NULL
) {
1250 free_name(rp
->temp_file
);
1252 rp
->temp_file
= NULL
;
1253 if (rp
->state
== build_failed
) {
1254 line
= get_prop(rp
->target
->prop
, line_prop
);
1256 line
->body
.line
.command_used
= NULL
;
1258 if (continue_after_error
||
1259 fatal_in_progress
||
1261 warning(gettext("Command failed for target `%s'"),
1262 rp
->command
? line2
->body
.line
.target
->string_mb
: rp
->target
->string_mb
);
1263 build_failed_seen
= true;
1266 * XXX??? - DMake needs to exit(),
1267 * but shouldn't call fatal().
1269 #ifdef PRINT_EXIT_STATUS
1270 warning("I'm in finish_children. rp->state == build_failed.");
1273 fatal(gettext("Command failed for target `%s'"),
1274 rp
->command
? line2
->body
.line
.target
->string_mb
: rp
->target
->string_mb
);
1278 delete_running_struct(rp
);
1283 goto bypass_for_loop_inc_4
;
1286 update_target(get_prop(rp
->target
->prop
, line_prop
),
1289 delete_running_struct(rp
);
1294 goto bypass_for_loop_inc_4
;
1297 rp_prev
= &rp
->next
;
1303 * dump_out_file(filename, err)
1305 * Write the contents of the file to stdout, then unlink the file.
1308 * filename Name of temp file containing output
1310 * Global variables used:
1313 dump_out_file(char *filename
, Boolean err
)
1316 char copybuf
[BUFSIZ
];
1318 int out_fd
= (err
? 2 : 1);
1320 if ((fd
= open(filename
, O_RDONLY
)) < 0) {
1321 fatal(gettext("open failed for output file %s: %s"),
1325 if (!silent
&& output_mode
!= txt2_mode
) {
1326 (void) fprintf(err
? stderr
: stdout
,
1328 gettext("%s --> Job errors\n") :
1329 gettext("%s --> Job output\n"),
1331 (void) fflush(err
? stderr
: stdout
);
1333 for (chars_read
= read(fd
, copybuf
, BUFSIZ
);
1335 chars_read
= read(fd
, copybuf
, BUFSIZ
)) {
1337 * Read buffers from the source file until end or error.
1339 if (write(out_fd
, copybuf
, chars_read
) < 0) {
1340 fatal(gettext("write failed for output file %s: %s"),
1346 (void) unlink(filename
);
1352 * Completes the processing for a target which was left running.
1355 * rp Running list entry for target
1357 * Global variables used:
1358 * debug_level Debug flag
1359 * recursion_level Indentation for debug output
1362 finish_doname(Running rp
)
1364 int auto_count
= rp
->auto_count
;
1365 Name
*automatics
= rp
->automatics
;
1366 Doname result
= rp
->state
;
1367 Name target
= rp
->target
;
1368 Name true_target
= rp
->true_target
;
1369 Property
*conditionals
;
1371 recursion_level
= rp
->recursion_level
;
1372 if (result
== build_ok
) {
1373 if (true_target
== NULL
) {
1374 (void) printf("Target = %s\n", target
->string_mb
);
1375 (void) printf(" State = %d\n", result
);
1376 fatal("Internal error: NULL true_target in finish_doname");
1378 /* If all went OK, set a nice timestamp */
1379 if (true_target
->stat
.time
== file_doesnt_exist
) {
1380 true_target
->stat
.time
= file_max_time
;
1383 target
->state
= result
;
1384 if (target
->is_member
) {
1387 /* Propagate the timestamp from the member file to the member */
1388 if ((target
->stat
.time
!= file_max_time
) &&
1389 ((member
= get_prop(target
->prop
, member_prop
)) != NULL
) &&
1390 (exists(member
->body
.member
.member
) > file_doesnt_exist
)) {
1393 exists(member->body.member.member);
1395 member
->body
.member
.member
->stat
.time
;
1399 * Check if we found any new auto dependencies when we
1402 if ((result
== build_ok
) && check_auto_dependencies(target
,
1405 if (debug_level
> 0) {
1406 (void) printf(gettext("%*sTarget `%s' acquired new dependencies from build, checking all dependencies\n"),
1409 true_target
->string_mb
);
1411 target
->rechecking_target
= true;
1412 target
->state
= build_running
;
1414 /* [tolik, Tue Mar 25 1997]
1415 * Fix for bug 4038824:
1416 * command line options set by conditional macros get dropped
1417 * rp->conditional_cnt and rp->conditional_targets must be copied
1418 * to new 'rp' during add_pending(). Set_conditionals() stores
1419 * rp->conditional_targets to the global variable 'conditional_targets'
1420 * Add_pending() will use this variable to set up 'rp'.
1422 conditionals
= set_conditionals(rp
->conditional_cnt
, rp
->conditional_targets
);
1428 reset_conditionals(rp
->conditional_cnt
, rp
->conditional_targets
, conditionals
);
1433 * new_running_struct()
1435 * Constructor for Running struct. Creates a structure and initializes
1439 static Running
new_running_struct()
1443 rp
= ALLOC(Running
);
1445 rp
->true_target
= NULL
;
1447 rp
->sprodep_value
= NULL
;
1448 rp
->sprodep_env
= NULL
;
1450 rp
->automatics
= NULL
;
1452 rp
->job_msg_id
= -1;
1453 rp
->stdout_file
= NULL
;
1454 rp
->stderr_file
= NULL
;
1455 rp
->temp_file
= NULL
;
1461 * add_running(target, true_target, command, recursion_level, auto_count,
1462 * automatics, do_get, implicit)
1464 * Adds a record on the running list for this target, which
1465 * was just spawned and is running.
1468 * target Target being built
1469 * true_target True target for target
1470 * command Running command.
1471 * recursion_level Debug indentation level
1472 * auto_count Count of automatic dependencies
1473 * automatics List of automatic dependencies
1474 * do_get Sccs get flag
1475 * implicit Implicit flag
1477 * Static variables used:
1478 * running_tail Tail of running list
1479 * process_running PID of process
1481 * Global variables used:
1482 * current_line Current line for target
1483 * current_target Current target being built
1484 * stderr_file Temporary file for stdout
1485 * stdout_file Temporary file for stdout
1486 * temp_file_name Temporary file for auto dependencies
1489 add_running(Name target
, Name true_target
, Property command
, int recursion_level
, int auto_count
, Name
*automatics
, Boolean do_get
, Boolean implicit
)
1494 rp
= new_running_struct();
1495 rp
->state
= build_running
;
1496 rp
->target
= target
;
1497 rp
->true_target
= true_target
;
1498 rp
->command
= command
;
1499 rp
->recursion_level
= recursion_level
;
1500 rp
->do_get
= do_get
;
1501 rp
->implicit
= implicit
;
1502 rp
->auto_count
= auto_count
;
1503 if (auto_count
> 0) {
1504 rp
->automatics
= (Name
*) getmem(auto_count
* sizeof (Name
));
1505 for (p
= rp
->automatics
; auto_count
> 0; auto_count
--) {
1506 *p
++ = *automatics
++;
1509 rp
->automatics
= NULL
;
1512 rp
->pid
= process_running
;
1513 process_running
= -1;
1516 rp
->job_msg_id
= job_msg_id
;
1517 rp
->stdout_file
= stdout_file
;
1518 rp
->stderr_file
= stderr_file
;
1519 rp
->temp_file
= temp_file_name
;
1522 store_conditionals(rp
);
1525 temp_file_name
= NULL
;
1526 current_target
= NULL
;
1527 current_line
= NULL
;
1529 running_tail
= &rp
->next
;
1533 * add_pending(target, recursion_level, do_get, implicit, redo)
1535 * Adds a record on the running list for a pending target
1536 * (waiting for its dependents to finish running).
1539 * target Target being built
1540 * recursion_level Debug indentation level
1541 * do_get Sccs get flag
1542 * implicit Implicit flag
1543 * redo True if this target is being redone
1545 * Static variables used:
1546 * running_tail Tail of running list
1549 add_pending(Name target
, int recursion_level
, Boolean do_get
, Boolean implicit
, Boolean redo
)
1552 rp
= new_running_struct();
1553 rp
->state
= build_pending
;
1554 rp
->target
= target
;
1555 rp
->recursion_level
= recursion_level
;
1556 rp
->do_get
= do_get
;
1557 rp
->implicit
= implicit
;
1559 store_conditionals(rp
);
1561 running_tail
= &rp
->next
;
1565 * add_serial(target, recursion_level, do_get, implicit)
1567 * Adds a record on the running list for a target which must be
1568 * executed in serial after others have finished.
1571 * target Target being built
1572 * recursion_level Debug indentation level
1573 * do_get Sccs get flag
1574 * implicit Implicit flag
1576 * Static variables used:
1577 * running_tail Tail of running list
1580 add_serial(Name target
, int recursion_level
, Boolean do_get
, Boolean implicit
)
1584 rp
= new_running_struct();
1585 rp
->target
= target
;
1586 rp
->recursion_level
= recursion_level
;
1587 rp
->do_get
= do_get
;
1588 rp
->implicit
= implicit
;
1589 rp
->state
= build_serial
;
1591 store_conditionals(rp
);
1593 running_tail
= &rp
->next
;
1597 * add_subtree(target, recursion_level, do_get, implicit)
1599 * Adds a record on the running list for a target which must be
1600 * executed in isolation after others have finished.
1603 * target Target being built
1604 * recursion_level Debug indentation level
1605 * do_get Sccs get flag
1606 * implicit Implicit flag
1608 * Static variables used:
1609 * running_tail Tail of running list
1612 add_subtree(Name target
, int recursion_level
, Boolean do_get
, Boolean implicit
)
1616 rp
= new_running_struct();
1617 rp
->target
= target
;
1618 rp
->recursion_level
= recursion_level
;
1619 rp
->do_get
= do_get
;
1620 rp
->implicit
= implicit
;
1621 rp
->state
= build_subtree
;
1623 store_conditionals(rp
);
1625 running_tail
= &rp
->next
;
1629 * store_conditionals(rp)
1631 * Creates an array of the currently active targets with conditional
1632 * macros (found in the chain conditional_targets) and puts that
1633 * array in the Running struct.
1636 * rp Running struct for storing chain
1638 * Global variables used:
1639 * conditional_targets Chain of current dynamic conditionals
1642 store_conditionals(Running rp
)
1647 if (conditional_targets
== NULL
) {
1648 rp
->conditional_cnt
= 0;
1649 rp
->conditional_targets
= NULL
;
1653 for (cond_name
= conditional_targets
;
1655 cond_name
= cond_name
->next
) {
1658 rp
->conditional_cnt
= cnt
;
1659 rp
->conditional_targets
= (Name
*) getmem(cnt
* sizeof(Name
));
1660 for (cond_name
= conditional_targets
;
1662 cond_name
= cond_name
->next
) {
1663 rp
->conditional_targets
[--cnt
] = cond_name
->name
;
1668 * parallel_ok(target, line_prop_must_exists)
1670 * Returns true if the target can be run in parallel
1673 * True if can run in parallel
1676 * target Target being tested
1678 * Global variables used:
1679 * all_parallel True if all targets default to parallel
1680 * only_parallel True if no targets default to parallel
1683 parallel_ok(Name target
, Boolean line_prop_must_exists
)
1690 assign
= make_refd
= false;
1691 if (((line
= get_prop(target
->prop
, line_prop
)) == NULL
) &&
1692 line_prop_must_exists
) {
1696 for (rule
= line
->body
.line
.command_used
;
1698 rule
= rule
->next
) {
1701 } else if (rule
->make_refd
) {
1708 } else if (target
->parallel
) {
1710 } else if (target
->no_parallel
) {
1712 } else if (all_parallel
) {
1714 } else if (only_parallel
) {
1716 } else if (make_refd
) {
1724 * is_running(target)
1726 * Returns true if the target is running.
1729 * True if target is running
1732 * target Target to check
1734 * Global variables used:
1735 * running_list List of running processes
1738 is_running(Name target
)
1742 if (target
->state
!= build_running
) {
1745 for (rp
= running_list
;
1746 rp
!= NULL
&& target
!= rp
->target
;
1751 return (rp
->state
== build_running
) ? true : false;
1756 * This function replaces the makesh binary.
1761 run_rule_commands(char *host
, char **commands
)
1763 Boolean always_exec
;
1768 Boolean silent_flag
;
1769 wchar_t *tmp_wcs_buffer
;
1773 case -1: /* Error */
1774 fatal(gettext("Could not fork child process for dmake job: %s"),
1778 /* To control the processed targets list is not the child's business */
1779 running_list
= NULL
;
1781 redirect_io(stdout_file
, (char*)NULL
);
1783 redirect_io(stdout_file
, stderr_file
);
1785 for (commands
= commands
;
1786 (*commands
!= (char *)NULL
);
1788 silent_flag
= silent
;
1790 always_exec
= false;
1791 while ((**commands
== (int) at_char
) ||
1792 (**commands
== (int) hyphen_char
) ||
1793 (**commands
== (int) plus_char
)) {
1794 if (**commands
== (int) at_char
) {
1797 if (**commands
== (int) hyphen_char
) {
1800 if (**commands
== (int) plus_char
) {
1805 if ((length
= strlen(*commands
)) >= MAXPATHLEN
) {
1806 tmp_wcs_buffer
= ALLOC_WC(length
+ 1);
1807 (void) mbstowcs(tmp_wcs_buffer
, *commands
, length
+ 1);
1808 command
= GETNAME(tmp_wcs_buffer
, FIND_LENGTH
);
1809 retmem(tmp_wcs_buffer
);
1811 MBSTOWCS(wcs_buffer
, *commands
);
1812 command
= GETNAME(wcs_buffer
, FIND_LENGTH
);
1814 if ((command
->hash
.length
> 0) &&
1816 (void) printf("%s\n", command
->string_mb
);
1818 result
= dosys(command
,
1821 false, /* bugs #4085164 & #4990057 */
1822 /* BOOLEAN(silent_flag && ignore), */
1825 if (result
== build_failed
) {
1827 (void) printf(gettext("The following command caused the error:\n%s\n"), command
->string_mb
);
1843 maybe_reread_make_state(void)
1845 /* Copying dosys()... */
1846 if (report_dependencies_level
== 0) {
1847 make_state
->stat
.time
= file_no_time
;
1848 (void) exists(make_state
);
1849 if (make_state_before
== make_state
->stat
.time
) {
1852 makefile_type
= reading_statefile
;
1853 if (read_trace_level
> 1) {
1854 trace_reader
= true;
1857 (void) read_simple_file(make_state
,
1864 trace_reader
= false;
1870 delete_running_struct(Running rp
)
1872 if ((rp
->conditional_cnt
> 0) &&
1873 (rp
->conditional_targets
!= NULL
)) {
1874 retmem_mb((char *) rp
->conditional_targets
);
1877 if ((rp
->auto_count
> 0) &&
1878 (rp
->automatics
!= NULL
)) {
1879 retmem_mb((char *) rp
->automatics
);
1882 if(rp
->sprodep_value
) {
1883 free_name(rp
->sprodep_value
);
1885 if(rp
->sprodep_env
) {
1886 retmem_mb(rp
->sprodep_env
);
1888 retmem_mb((char *) rp
);