m3core/src/thread/Common/ThreadInternal.c
/* Copyright (C) 1989, Digital Equipment Corporation */
/* All rights reserved. */
/* See the file COPYRIGHT for a full description. */
#include "m3core.h"
#include <poll.h>
M3_EXTERNC_BEGIN
#if M3_HAS_VISIBILITY
#pragma GCC visibility push(hidden)
#endif
M3_NO_INLINE static int /*bool*/
ThreadInternal__StackGrowsDownHelper (volatile char* a)
/* Inlining could potentially reverse the relative placements,
* leading to an incorrect result! Recursion is used to
* help defeat inlining optimizer, though a smart compiler
* could still inline. */
{
volatile char b;
return a ? (&b < a) : ThreadInternal__StackGrowsDownHelper (&b);
}
M3_NO_INLINE M3_DLL_LOCAL int /*bool*/ __cdecl
ThreadInternal__StackGrowsDown (void)
/* Most stacks do grow down, which is why we don't
name this more generally "StackDirection" or such. */
{
int a = ThreadInternal__StackGrowsDownHelper (0);
#ifdef __hppa__
assert(!a);
#else
assert(a);
#endif
return a;
}
#ifndef _WIN32
enum {WaitResult_Ready, WaitResult_Error, WaitResult_FDError, WaitResult_Timeout};
#define MILLION (1000 * 1000)
M3_DLL_LOCAL
int
__cdecl
ThreadInternal__Poll(int fd,
int/*boolean*/ read,
LONGREAL/*Time.T*/ m3timeout)
{
int r;
struct pollfd p;
ZERO_MEMORY(p);
p.fd = fd;
p.events = POLLERR | (read ? POLLIN : POLLOUT);
p.revents = 0;
r = poll(&p, 1, (m3timeout < 0) ? -1 : (m3timeout * MILLION));
assert(r == -1 || r == 0 || r == 1);
if (r == -1)
return WaitResult_Error;
else if (r == 0)
return WaitResult_Timeout;
else if ((read && (p.revents & POLLIN)) || ((!read) && (p.revents & POLLOUT)))
return WaitResult_Ready;
else
return WaitResult_FDError;
}
M3_DLL_LOCAL
int
__cdecl
ThreadInternal__Select(int nfds,
ADDRESS read,
ADDRESS write,
ADDRESS xcept, /* except is keyword on OSF/1 */
LONGREAL/*Time.T*/ m3timeout)
{
struct timeval timeout;
double n = { 0 };
if (m3timeout < 0)
return select(nfds, read, write, xcept, NULL);
ZERO_MEMORY(timeout);
timeout.tv_usec = modf(m3timeout, &n) * MILLION;
timeout.tv_sec = n;
return select(nfds, read, write, xcept, &timeout);
}
#endif
M3_EXTERNC_END