Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting photon/thread/* to Windows with mingw #185

Merged
merged 4 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions common/alog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

#ifdef _WIN64
#define _POSIX_C_SOURCE 1
#endif
#include "alog.h"
#include "lockfree_queue.h"
#include "photon/thread/thread.h"
Expand Down Expand Up @@ -251,7 +254,11 @@ class LogOutputFile final : public BaseLogOutput {
if (log_file_fd < 0) return;
uint64_t length = end - begin;
iovec iov{(void*)begin, length};
#ifndef _WIN64
::writev(log_file_fd, &iov, 1); // writev() is atomic, whereas write() is not
#else
::write(log_file_fd, iov.iov_base, iov.iov_len);
#endif
throttle_block();
if (log_file_name && log_file_size_limit) {
log_file_size += length;
Expand Down
10 changes: 5 additions & 5 deletions common/test/test_alog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class LogOutputTest : public ILogOutput {
}
const char* log_start() const {
auto ls = _log_buf;
for (int i = 0; i < 4; i++)
for (int i = 0; i < 4; i++)
ls = strchr(ls, '|') + 1;
ls = strchr(ls, ':') + 1;
return ls;
Expand Down Expand Up @@ -493,7 +493,7 @@ void testnull_func() {
}

void segfault() {
char *pc = nullptr;
volatile char *pc = nullptr;
*pc = 'w'; //this must trigger sigfault
}

Expand Down Expand Up @@ -522,21 +522,21 @@ TEST(ALog, LOG_LIMIT) {
auto x = 0;
for (int i=0; i< 1000000;i++) {
// every 60 secs print only once
LOG_EVERY_T(60, LOG_INFO("LOG once every 60 second ...", x++));
LOG_EVERY_T(60, LOG_INFO("LOG once every 60 second ...", x++));
}
// suppose to print and evaluate 1 times
EXPECT_EQ(1, x);
x = 0;
for (int i=0; i< 1000000;i++) {
// every 100`000 times logs only only once
LOG_EVERY_N(100000, LOG_INFO("LOG once every 100000 logs ...", x++));
LOG_EVERY_N(100000, LOG_INFO("LOG once every 100000 logs ...", x++));
}
// suppose to print and evaluate 1`000`000 / 100`000 = 10 times
EXPECT_EQ(10, x);
x = 0;
for (int i=0; i< 1000000;i++) {
// logs only 10 records.
LOG_FIRST_N(10, LOG_INFO("LOG first 10 logs ...", x++));
LOG_FIRST_N(10, LOG_INFO("LOG first 10 logs ...", x++));
}
// suppose to print and evaluate 10 times
EXPECT_EQ(10, x);
Expand Down
8 changes: 4 additions & 4 deletions common/tuple-assistance.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ struct callable<F&> : public callable<F> {};
template <class F>
struct callable<F&&> : public callable<F> {};

#if __cplusplus < 201700
// #if __cplusplus < 201700
template <typename F, typename Tuple, std::size_t... I>
constexpr inline decltype(auto) apply_impl(F&& f, Tuple&& t,
std::index_sequence<I...>) {
Expand All @@ -90,9 +90,9 @@ constexpr inline decltype(auto) apply(F&& f, Tuple&& t) {
std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
}

#else
using std::apply;
#endif
// #else
// using std::apply;
// #endif

template <typename P, size_t I, typename... Ts>
struct do_enumerate;
Expand Down
Empty file added third_party/include/arpa/inet.h
Empty file.
Empty file.
Empty file.
Empty file.
16 changes: 16 additions & 0 deletions third_party/include/sys/uio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef SYS_UIO_H
#define SYS_UIO_H

#include <inttypes.h>
#include <unistd.h>

struct iovec
{
void *iov_base; /* Base address of a memory region for input or output */
size_t iov_len; /* The size of the memory pointed to by iov_base */
};

ssize_t readv(int fildes, const struct iovec *iov, int iovcnt);
ssize_t writev(int fildes, const struct iovec *iov, int iovcnt);

#endif /* SYS_UIO_H */
4 changes: 4 additions & 0 deletions thread/test/build-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
g++ -std=c++17 -I ../../include/ -I../../third_party/include -DThreadUT test.cpp x.cpp \
../thread-pool.cpp ../workerpool.cpp ../thread-key.cpp \
../../common/identity-pool.cpp ../../common/alog.cpp -lgtest -lgflags -O2

50 changes: 38 additions & 12 deletions thread/test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ limitations under the License.
#include <errno.h>
#include <math.h>
#include <string>
#include <random>
#include <stdlib.h>
#include <queue>
#include <algorithm>
#include <sys/time.h>
Expand Down Expand Up @@ -73,7 +73,7 @@ uint64_t isqrt(uint64_t n)
if (n == 0)
return 0;

uint64_t x = 1L << (sizeof(n) * 8 / 2);
uint64_t x = 1ULL << (sizeof(n) * 8 / 2);
while (true)
{
auto y = (x + n / x) / 2;
Expand Down Expand Up @@ -773,7 +773,7 @@ thread_local photon::rwlock rwl;

void *rwlocktest(void* args) {
uint64_t carg = (uint64_t) args;
auto mode = carg & ((1UL<<32) -1);
auto mode = carg & ((1ULL<<32) -1);
auto id = carg >> 32;
// LOG_DEBUG("locking ", VALUE(id), VALUE(mode));
rwl.lock(mode);
Expand Down Expand Up @@ -885,8 +885,8 @@ void vcpu_start(uint32_t i)
TEST(saturated, add)
{
uint64_t cases[][3] = {
{10UL, -1UL, -1UL},
{10UL, -9UL, -1UL},
{10UL, -1ULL, -1ULL},
{10UL, -9ULL, -1ULL},
{1UL, 2UL, 3UL},
{10UL, 3UL, 13UL},
{100UL, 4UL, 104UL},
Expand Down Expand Up @@ -1058,7 +1058,7 @@ photon::rwlock srwl;

void *smprwlocktest(void* args) {
uint64_t carg = (uint64_t) args;
auto mode = carg & ((1UL<<32) -1);
auto mode = carg & ((1ULL<<32) -1);
auto id = carg >> 32;
// LOG_DEBUG("locking ", VALUE(id), VALUE(mode));
srwl.lock(mode);
Expand Down Expand Up @@ -1123,7 +1123,7 @@ void* test_smp_cvar_recver(void* args_)
args->recvd++;
}
if (args->senders == 0) break;
thread_usleep(random() % 128);
thread_usleep(rand() % 128);
}
args->recvers--;
return 0;
Expand All @@ -1145,7 +1145,7 @@ void* test_smp_cvar_sender(void* args_)
// LOG_DEBUG("notify_all()ed to ` threads", n);
args->sent += n;
}
thread_usleep(random() % 128);
thread_usleep(rand() % 128);
}
args->senders--;
return 0;
Expand All @@ -1160,7 +1160,7 @@ void* test_smp_cvar(void* args_)
if (args->senders == 0)
while(args->recvers > 0)
{
thread_usleep(random() % 128);
thread_usleep(rand() % 128);
auto n = args->cvar.notify_all();
args->sent += n;
}
Expand Down Expand Up @@ -1202,7 +1202,7 @@ void* test_smp_semaphore(void* args_)
TEST(smp, semaphore)
{
smp_semaphore_args args;
auto n = args.n = 18UL;
auto n = args.n = 10UL;
args.sem.signal(n/2);
std_threads_create_join(n, &photon_do,
n*n, &test_smp_semaphore, &args);
Expand Down Expand Up @@ -1465,12 +1465,38 @@ TEST(workpool, async_work_lambda_threadpool_append) {
LOG_INFO("DONE");
}

#if defined(_WIN64)
#define SAVE_REG(R) register uint64_t R asm(#R); volatile uint64_t saved_##R = R;
#define CHECK_REG(R) asm volatile ("" : "=m"(saved_##R)); if (saved_##R != R) puts(#R " differs after context switch!");
#else
#define SAVE_REG(R)
#define CHECK_REG(R)
#endif

void* waiter(void* arg) {
auto p = (int*)arg;
LOG_INFO("Start", VALUE(*p));
LOG_INFO("Start", VALUE(p), VALUE(*p));
SAVE_REG(rbx);
SAVE_REG(rsi);
SAVE_REG(rdi);
SAVE_REG(r12);
SAVE_REG(r13);
SAVE_REG(r14);
SAVE_REG(r15);
SAVE_REG(rbp);
SAVE_REG(rsp);
photon::thread_usleep(1UL * 1000 * 1000);
CHECK_REG(rbx);
CHECK_REG(rsi);
CHECK_REG(rdi);
CHECK_REG(r12);
CHECK_REG(r13);
CHECK_REG(r14);
CHECK_REG(r15);
CHECK_REG(rbp);
CHECK_REG(rsp);
(*p)--;
LOG_INFO("Fin", VALUE(*p));
LOG_INFO("Fin", VALUE(p), VALUE(*p));
return nullptr;
}

Expand Down
15 changes: 15 additions & 0 deletions thread/test/x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,18 @@ int DevNull(void* x, int)
}

int (*pDevNull)(void*, int) = &DevNull;

#ifdef ThreadUT

#include "../thread.h"
namespace photon {
int init(uint64_t event_engine, uint64_t io_engine) {
return vcpu_init();
}

int fini() {
return vcpu_fini();
}
}

#endif