VirtualBox

source: kBuild/trunk/src/kmk/w32/w32os.c@ 3633

Last change on this file since 3633 was 3297, checked in by bird, 5 years ago

kmk/win: Two CONFIG_NEW_WIN_CHILDREN fixes (inverted #ifdef's), can now use all threads on systems with more than 64 (for whatever good it does).

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1/* Windows32-based operating system interface for GNU Make.
2Copyright (C) 2016 Free Software Foundation, Inc.
3This file is part of GNU Make.
4
5GNU Make is free software; you can redistribute it and/or modify it under the
6terms of the GNU General Public License as published by the Free Software
7Foundation; either version 3 of the License, or (at your option) any later
8version.
9
10GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
11WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#include "makeint.h"
18
19#include <stdio.h>
20#include <string.h>
21
22#include <windows.h>
23#include <process.h>
24#include <io.h>
25#include "pathstuff.h"
26#ifndef CONFIG_NEW_WIN_CHILDREN
27# include "sub_proc.h"
28#else
29# include "winchildren.h"
30#endif
31#include "w32err.h"
32#include "os.h"
33#include "debug.h"
34
35/* This section provides OS-specific functions to support the jobserver. */
36
37static char jobserver_semaphore_name[MAX_PATH + 1];
38static HANDLE jobserver_semaphore = NULL;
39
40unsigned int
41jobserver_setup (int slots)
42{
43#ifndef CONFIG_NEW_WIN_CHILDREN
44 /* sub_proc.c cannot wait for more than MAXIMUM_WAIT_OBJECTS objects
45 * and one of them is the job-server semaphore object. Limit the
46 * number of available job slots to (MAXIMUM_WAIT_OBJECTS - 1). */
47
48 if (slots >= MAXIMUM_WAIT_OBJECTS)
49 {
50 slots = MAXIMUM_WAIT_OBJECTS - 1;
51 DB (DB_JOBS, (_("Jobserver slots limited to %d\n"), slots));
52 }
53#endif
54
55 sprintf (jobserver_semaphore_name, "gmake_semaphore_%d", _getpid ());
56
57 jobserver_semaphore = CreateSemaphore (
58 NULL, /* Use default security descriptor */
59 slots, /* Initial count */
60 slots, /* Maximum count */
61 jobserver_semaphore_name); /* Semaphore name */
62
63 if (jobserver_semaphore == NULL)
64 {
65 DWORD err = GetLastError ();
66 const char *estr = map_windows32_error_to_string (err);
67 ONS (fatal, NILF,
68 _("creating jobserver semaphore: (Error %ld: %s)"), err, estr);
69 }
70
71 return 1;
72}
73
74unsigned int
75jobserver_parse_auth (const char *auth)
76{
77 jobserver_semaphore = OpenSemaphore (
78 SEMAPHORE_ALL_ACCESS, /* Semaphore access setting */
79 FALSE, /* Child processes DON'T inherit */
80 auth); /* Semaphore name */
81
82 if (jobserver_semaphore == NULL)
83 {
84 DWORD err = GetLastError ();
85 const char *estr = map_windows32_error_to_string (err);
86 fatal (NILF, strlen (auth) + INTSTR_LENGTH + strlen (estr),
87 _("internal error: unable to open jobserver semaphore '%s': (Error %ld: %s)"),
88 auth, err, estr);
89 }
90 DB (DB_JOBS, (_("Jobserver client (semaphore %s)\n"), auth));
91
92 return 1;
93}
94
95char *
96jobserver_get_auth ()
97{
98 return xstrdup (jobserver_semaphore_name);
99}
100
101unsigned int
102jobserver_enabled ()
103{
104 return jobserver_semaphore != NULL;
105}
106
107/* Close jobserver semaphore */
108void
109jobserver_clear ()
110{
111 if (jobserver_semaphore != NULL)
112 {
113 CloseHandle (jobserver_semaphore);
114 jobserver_semaphore = NULL;
115 }
116}
117
118void
119jobserver_release (int is_fatal)
120{
121 if (! ReleaseSemaphore (
122 jobserver_semaphore, /* handle to semaphore */
123 1, /* increase count by one */
124 NULL)) /* not interested in previous count */
125 {
126 if (is_fatal)
127 {
128 DWORD err = GetLastError ();
129 const char *estr = map_windows32_error_to_string (err);
130 ONS (fatal, NILF,
131 _("release jobserver semaphore: (Error %ld: %s)"), err, estr);
132 }
133 perror_with_name ("release_jobserver_semaphore", "");
134 }
135}
136
137unsigned int
138jobserver_acquire_all ()
139{
140 unsigned int tokens = 0;
141 while (1)
142 {
143 DWORD dwEvent = WaitForSingleObject (
144 jobserver_semaphore, /* Handle to semaphore */
145 0); /* DON'T wait on semaphore */
146
147 if (dwEvent != WAIT_OBJECT_0)
148 return tokens;
149
150 ++tokens;
151 }
152}
153
154void
155jobserver_signal ()
156{
157}
158
159void jobserver_pre_child (int recursive)
160{
161}
162
163void jobserver_post_child (int recursive)
164{
165}
166
167void
168jobserver_pre_acquire ()
169{
170}
171
172/* Returns 1 if we got a token, or 0 if a child has completed.
173 The Windows implementation doesn't support load detection. */
174unsigned int
175jobserver_acquire (int timeout)
176{
177#ifndef CONFIG_NEW_WIN_CHILDREN
178 HANDLE handles[MAXIMUM_WAIT_OBJECTS + 1]; /* bird: + 1 to prevent trashing the stack. */
179#else
180 HANDLE handles[2];
181#endif
182 DWORD dwHandleCount;
183 DWORD dwEvent;
184
185 /* Add jobserver semaphore to first slot. */
186 handles[0] = jobserver_semaphore;
187
188#ifndef CONFIG_NEW_WIN_CHILDREN
189 /* Build array of handles to wait for. */
190 dwHandleCount = 1 + process_set_handles (&handles[1]);
191 dwEvent = WaitForMultipleObjects (
192 dwHandleCount, /* number of objects in array */
193 handles, /* array of objects */
194 FALSE, /* wait for any object */
195 INFINITE); /* wait until object is signalled */
196#else
197 /* Add the completed children event as the 2nd one. */
198 handles[1] = (HANDLE)MkWinChildGetCompleteEventHandle ();
199 if (handles[1] == NULL)
200 return 0;
201 dwHandleCount = 2;
202 dwEvent = WaitForMultipleObjectsEx (dwHandleCount,
203 handles,
204 FALSE /*bWaitAll*/,
205 256, /* INFINITE - paranoia, only wait 256 ms before checking again. */
206 TRUE /*bAlertable*/);
207#endif
208
209 if (dwEvent == WAIT_FAILED)
210 {
211 DWORD err = GetLastError ();
212 const char *estr = map_windows32_error_to_string (err);
213 ONS (fatal, NILF,
214 _("semaphore or child process wait: (Error %ld: %s)"),
215 err, estr);
216 }
217
218 /* WAIT_OBJECT_0 indicates that the semaphore was signalled. */
219 return dwEvent == WAIT_OBJECT_0;
220}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette