Cygwin: implement sched_getcpu
* create new function __get_cpus_per_group to evaluate # of CPU groups * Call from format_proc_cpuinfo and sched_getcpu * Bump API minor version Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
c233d42264
commit
1e0a1f59d9
|
@ -580,6 +580,7 @@ LoadDLLfunc (if_indextoname, 8, iphlpapi)
|
||||||
LoadDLLfunc (if_nametoindex, 4, iphlpapi)
|
LoadDLLfunc (if_nametoindex, 4, iphlpapi)
|
||||||
|
|
||||||
LoadDLLfuncEx2 (DiscardVirtualMemory, 8, kernel32, 1, 127)
|
LoadDLLfuncEx2 (DiscardVirtualMemory, 8, kernel32, 1, 127)
|
||||||
|
LoadDLLfunc (GetCurrentProcessorNumberEx, 4, kernel32)
|
||||||
LoadDLLfuncEx (GetLogicalProcessorInformationEx, 12, kernel32, 1)
|
LoadDLLfuncEx (GetLogicalProcessorInformationEx, 12, kernel32, 1)
|
||||||
LoadDLLfunc (GetSystemTimePreciseAsFileTime, 4, kernel32)
|
LoadDLLfunc (GetSystemTimePreciseAsFileTime, 4, kernel32)
|
||||||
LoadDLLfuncEx (PrefetchVirtualMemory, 16, kernel32, 1)
|
LoadDLLfuncEx (PrefetchVirtualMemory, 16, kernel32, 1)
|
||||||
|
|
|
@ -1249,6 +1249,7 @@ scandirat SIGFE
|
||||||
scanf SIGFE
|
scanf SIGFE
|
||||||
sched_get_priority_max SIGFE
|
sched_get_priority_max SIGFE
|
||||||
sched_get_priority_min SIGFE
|
sched_get_priority_min SIGFE
|
||||||
|
sched_getcpu SIGFE
|
||||||
sched_getparam SIGFE
|
sched_getparam SIGFE
|
||||||
sched_getscheduler NOSIGFE
|
sched_getscheduler NOSIGFE
|
||||||
sched_rr_get_interval SIGFE
|
sched_rr_get_interval SIGFE
|
||||||
|
|
|
@ -600,7 +600,6 @@ format_proc_stat (void *, char *&destbuf)
|
||||||
return eobuf - buf;
|
return eobuf - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define add_size(p,s) ((p) = ((__typeof__(p))((PBYTE)(p)+(s))))
|
|
||||||
#define print(x) { bufptr = stpcpy (bufptr, (x)); }
|
#define print(x) { bufptr = stpcpy (bufptr, (x)); }
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
|
@ -640,46 +639,7 @@ format_proc_cpuinfo (void *, char *&destbuf)
|
||||||
char *bufptr = buf;
|
char *bufptr = buf;
|
||||||
|
|
||||||
//WORD num_cpu_groups = 1; /* Pre Windows 7, only one group... */
|
//WORD num_cpu_groups = 1; /* Pre Windows 7, only one group... */
|
||||||
WORD num_cpu_per_group = 64; /* ...and a max of 64 CPUs. */
|
WORD num_cpu_per_group = __get_cpus_per_group ();
|
||||||
|
|
||||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX lpi =
|
|
||||||
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) tp.c_get ();
|
|
||||||
DWORD lpi_size = NT_MAX_PATH;
|
|
||||||
|
|
||||||
/* Fake a SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX group info block on Vista
|
|
||||||
systems. This may be over the top but if the below code just using
|
|
||||||
ActiveProcessorCount turns out to be insufficient, we can build on that. */
|
|
||||||
if (!wincap.has_processor_groups ()
|
|
||||||
|| !GetLogicalProcessorInformationEx (RelationGroup, lpi, &lpi_size))
|
|
||||||
{
|
|
||||||
lpi_size = sizeof *lpi;
|
|
||||||
lpi->Relationship = RelationGroup;
|
|
||||||
lpi->Size = lpi_size;
|
|
||||||
lpi->Group.MaximumGroupCount = 1;
|
|
||||||
lpi->Group.ActiveGroupCount = 1;
|
|
||||||
lpi->Group.GroupInfo[0].MaximumProcessorCount = wincap.cpu_count ();
|
|
||||||
lpi->Group.GroupInfo[0].ActiveProcessorCount
|
|
||||||
= __builtin_popcountl (wincap.cpu_mask ());
|
|
||||||
lpi->Group.GroupInfo[0].ActiveProcessorMask = wincap.cpu_mask ();
|
|
||||||
}
|
|
||||||
|
|
||||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX plpi = lpi;
|
|
||||||
for (DWORD size = lpi_size; size > 0;
|
|
||||||
size -= plpi->Size, add_size (plpi, plpi->Size))
|
|
||||||
if (plpi->Relationship == RelationGroup)
|
|
||||||
{
|
|
||||||
//num_cpu_groups = plpi->Group.MaximumGroupCount;
|
|
||||||
/* Turns out, there are systems with a MaximumProcessorCount not
|
|
||||||
reflecting the actually available CPUs. The ActiveProcessorCount
|
|
||||||
is correct though. So we just use ActiveProcessorCount for now,
|
|
||||||
hoping the best. If it turns out that we have to handle more
|
|
||||||
complex CPU layouts with weird ActiveProcessorMasks, we can
|
|
||||||
do that by restructuring the subsequent CPU loop. */
|
|
||||||
num_cpu_per_group
|
|
||||||
= plpi->Group.GroupInfo[0].ActiveProcessorCount;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cpu_num_p = wcpcpy (cpu_key, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION"
|
cpu_num_p = wcpcpy (cpu_key, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION"
|
||||||
"\\System\\CentralProcessor\\");
|
"\\System\\CentralProcessor\\");
|
||||||
|
|
|
@ -498,12 +498,13 @@ details. */
|
||||||
327: Export pthread_tryjoin_np, pthread_timedjoin_np.
|
327: Export pthread_tryjoin_np, pthread_timedjoin_np.
|
||||||
328: Export aio_cancel, aio_error, aio_fsync, aio_read, aio_return,
|
328: Export aio_cancel, aio_error, aio_fsync, aio_read, aio_return,
|
||||||
aio_suspend, aio_write, lio_listio.
|
aio_suspend, aio_write, lio_listio.
|
||||||
|
329: Export sched_getcpu..
|
||||||
|
|
||||||
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
||||||
sigaltstack, sethostname. */
|
sigaltstack, sethostname. */
|
||||||
|
|
||||||
#define CYGWIN_VERSION_API_MAJOR 0
|
#define CYGWIN_VERSION_API_MAJOR 0
|
||||||
#define CYGWIN_VERSION_API_MINOR 328
|
#define CYGWIN_VERSION_API_MINOR 329
|
||||||
|
|
||||||
/* There is also a compatibity version number associated with the shared memory
|
/* There is also a compatibity version number associated with the shared memory
|
||||||
regions. It is incremented when incompatible changes are made to the shared
|
regions. It is incremented when incompatible changes are made to the shared
|
||||||
|
|
|
@ -15,6 +15,7 @@ details. */
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
#include "tls_pbuf.h"
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
check_invalid_virtual_addr (const void *s, unsigned sz)
|
check_invalid_virtual_addr (const void *s, unsigned sz)
|
||||||
|
@ -959,3 +960,55 @@ SetThreadName(DWORD dwThreadID, const char* threadName)
|
||||||
__except (NO_ERROR)
|
__except (NO_ERROR)
|
||||||
__endtry
|
__endtry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define add_size(p,s) ((p) = ((__typeof__(p))((PBYTE)(p)+(s))))
|
||||||
|
|
||||||
|
WORD
|
||||||
|
__get_cpus_per_group (void)
|
||||||
|
{
|
||||||
|
static WORD num_cpu_per_group = 0;
|
||||||
|
|
||||||
|
tmp_pathbuf tp;
|
||||||
|
|
||||||
|
if (num_cpu_per_group)
|
||||||
|
return num_cpu_per_group;
|
||||||
|
|
||||||
|
num_cpu_per_group = 64;
|
||||||
|
|
||||||
|
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX lpi =
|
||||||
|
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) tp.c_get ();
|
||||||
|
DWORD lpi_size = NT_MAX_PATH;
|
||||||
|
|
||||||
|
/* Fake a SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX group info block on Vista
|
||||||
|
systems. This may be over the top but if the below code just using
|
||||||
|
ActiveProcessorCount turns out to be insufficient, we can build on that. */
|
||||||
|
if (!wincap.has_processor_groups ()
|
||||||
|
|| !GetLogicalProcessorInformationEx (RelationGroup, lpi, &lpi_size))
|
||||||
|
{
|
||||||
|
lpi_size = sizeof *lpi;
|
||||||
|
lpi->Relationship = RelationGroup;
|
||||||
|
lpi->Size = lpi_size;
|
||||||
|
lpi->Group.MaximumGroupCount = 1;
|
||||||
|
lpi->Group.ActiveGroupCount = 1;
|
||||||
|
lpi->Group.GroupInfo[0].MaximumProcessorCount = wincap.cpu_count ();
|
||||||
|
lpi->Group.GroupInfo[0].ActiveProcessorCount
|
||||||
|
= __builtin_popcountl (wincap.cpu_mask ());
|
||||||
|
lpi->Group.GroupInfo[0].ActiveProcessorMask = wincap.cpu_mask ();
|
||||||
|
}
|
||||||
|
|
||||||
|
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX plpi = lpi;
|
||||||
|
for (DWORD size = lpi_size; size > 0;
|
||||||
|
size -= plpi->Size, add_size (plpi, plpi->Size))
|
||||||
|
if (plpi->Relationship == RelationGroup)
|
||||||
|
{
|
||||||
|
/* There are systems with a MaximumProcessorCount not reflecting the
|
||||||
|
actually available CPUs. The ActiveProcessorCount is correct
|
||||||
|
though. So we just use ActiveProcessorCount for now, hoping for
|
||||||
|
the best. */
|
||||||
|
num_cpu_per_group
|
||||||
|
= plpi->Group.GroupInfo[0].ActiveProcessorCount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_cpu_per_group;
|
||||||
|
}
|
||||||
|
|
|
@ -119,4 +119,6 @@ extern "C" HANDLE WINAPI CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func,
|
||||||
|
|
||||||
void SetThreadName (DWORD dwThreadID, const char* threadName);
|
void SetThreadName (DWORD dwThreadID, const char* threadName);
|
||||||
|
|
||||||
|
WORD __get_cpus_per_group (void);
|
||||||
|
|
||||||
#endif /*_MISCFUNCS_H*/
|
#endif /*_MISCFUNCS_H*/
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
What's new:
|
What's new:
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
- New API: clearenv, pthread_tryjoin_np, pthread_timedjoin_np.
|
- New APIs: clearenv, pthread_tryjoin_np, pthread_timedjoin_np,
|
||||||
|
sched_getcpu.
|
||||||
|
|
||||||
- New APIs: aio_cancel, aio_error, aio_fsync, aio_read, aio_return,
|
- New APIs: aio_cancel, aio_error, aio_fsync, aio_read, aio_return,
|
||||||
aio_suspend, aio_write, lio_listio.
|
aio_suspend, aio_write, lio_listio.
|
||||||
|
|
|
@ -411,4 +411,17 @@ sched_yield ()
|
||||||
SwitchToThread ();
|
SwitchToThread ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sched_getcpu ()
|
||||||
|
{
|
||||||
|
if (!wincap.has_processor_groups ())
|
||||||
|
return (int) GetCurrentProcessorNumber ();
|
||||||
|
|
||||||
|
PROCESSOR_NUMBER pnum;
|
||||||
|
|
||||||
|
GetCurrentProcessorNumberEx (&pnum);
|
||||||
|
return pnum.Group * __get_cpus_per_group () + pnum.Number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} /* extern C */
|
||||||
|
|
|
@ -17,7 +17,7 @@ SO_RCVTIMEO and SO_SNDTIMEO socket options are now honored.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
New API: clearenv, pthread_tryjoin_np, pthread_timedjoin_np.
|
New APIs: clearenv, pthread_tryjoin_np, pthread_timedjoin_np, sched_getcpu.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
|
|
|
@ -1375,6 +1375,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
||||||
rawmemchr
|
rawmemchr
|
||||||
removexattr
|
removexattr
|
||||||
scandirat
|
scandirat
|
||||||
|
sched_getcpu
|
||||||
setxattr
|
setxattr
|
||||||
sincos
|
sincos
|
||||||
sincosf
|
sincosf
|
||||||
|
|
Loading…
Reference in New Issue