Skip to content

Commit

Permalink
example: upgrade and port unbufcpy to iocp4linux
Browse files Browse the repository at this point in the history
  • Loading branch information
microcai committed Jan 5, 2025
1 parent 01e4343 commit 8e131e8
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 198 deletions.
4 changes: 1 addition & 3 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,4 @@ add_executable(example_on_zhihu zhihu.cpp)

add_executable(echo_client_stackfull echo_client/echo_client_stackfull.cpp)

if(WIN32)
add_subdirectory(unbufcpy)
endif()
add_subdirectory(unbufcpy)
2 changes: 1 addition & 1 deletion example/unbufcpy/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

add_executable(unbufcp1 unbufcp1/unbufcp1.c)
add_executable(unbufcp2 unbufcp2/unbufcp2.c)
add_executable(unbufcp2 unbufcp2/unbufcp2.cpp)
129 changes: 68 additions & 61 deletions example/unbufcpy/unbufcp1/unbufcp1.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,42 @@ Module Name:
#pragma warning(disable:4100)
#endif

#ifdef _WIN32
#include <windows.h>
#else
#include "iocp.h"
#include <time.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#ifndef _WIN32

DWORD GetTickCount()
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec* 1000 + ts.tv_nsec/1000000;
}

#endif

//
// File handles for the copy operation. All read operations are
// from SourceFile. All write operations are to DestFile.
//
HANDLE SourceFile;
HANDLE DestFile;

#ifdef _WIN32
//
//version information
//
OSVERSIONINFO ver;

#endif

//
// I/O completion port. All read and writes to the files complete
// to this port.
Expand Down Expand Up @@ -112,9 +131,7 @@ CopyLoop(
ULARGE_INTEGER FileSize
);

int
__cdecl
main(
int main(
int argc,
char *argv[]
)
Expand All @@ -124,14 +141,17 @@ main(
BOOL Success;
DWORD Status;
DWORD StartTime, EndTime;
SYSTEM_INFO SystemInfo;
HANDLE BufferedHandle;

if (argc != 3) {
fprintf(stderr, "Usage: %s SourceFile DestinationFile\n", argv[0]);
exit(1);
}

#ifdef _WIN32

SYSTEM_INFO SystemInfo;

//
//confirm we are running on Windows NT 3.5 or greater, if not, display notice and
//terminate. Completion ports are only supported on Win32 & Win32s. Creating a
Expand Down Expand Up @@ -171,7 +191,9 @@ main(
//
GetSystemInfo(&SystemInfo);
PageSize = SystemInfo.dwPageSize;

#else
PageSize = 4096;
#endif
//
// Open the source file and create the destination file.
// Use FILE_FLAG_NO_BUFFERING to avoid polluting the
Expand Down Expand Up @@ -235,51 +257,41 @@ main(
//We know already that we are running on NT, or else we wouldn't have
//gotten this far, so lets see what version we are running on.
//
if (ver.dwMajorVersion == 3 && ver.dwMinorVersion == 50)
//
//we're running on NT 3.5 - Completion Ports exists.
//
IoPort = CreateIoCompletionPort(SourceFile, //file handle to associate with I/O completion port.
NULL, //optional handle to existing I/O completion port.
ReadKey, //completion key.
1); //# of threads allowed to execute concurrently.
else
{
//
//we are running on NT 3.51 or greater.
//Create the I/O Completion Port
//
IoPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,//file handle to associate with I/O completion port
NULL, //optional handle to existing I/O completion port
ReadKey, //completion key
1); //# of threads allowed to execute concurrently


if (IoPort == NULL) {
fprintf(stderr, "failed to create ReadPort, error %d\n", GetLastError());
exit(1);
}

//
//If we need to, aka we're running on NT 3.51, let's associate a file handle with the
//completion port.
//

IoPort = CreateIoCompletionPort(SourceFile,
IoPort,
ReadKey,
1);

if (IoPort == NULL)
{
fprintf(stderr,
"failed to create IoPort, error %d\n",
GetLastError());

exit(1);

}
}

//
//we are running on NT 3.51 or greater.
//Create the I/O Completion Port
//
IoPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,//file handle to associate with I/O completion port
NULL, //optional handle to existing I/O completion port
ReadKey, //completion key
1); //# of threads allowed to execute concurrently


if (IoPort == NULL) {
fprintf(stderr, "failed to create ReadPort, error %d\n", GetLastError());
exit(1);
}

//
//If we need to, aka we're running on NT 3.51, let's associate a file handle with the
//completion port.
//

IoPort = CreateIoCompletionPort(SourceFile,
IoPort,
ReadKey,
1);

if (IoPort == NULL)
{
fprintf(stderr,
"failed to create IoPort, error %d\n",
GetLastError());

exit(1);

}

//
// Associate the destination file handle with the
Expand Down Expand Up @@ -360,10 +372,7 @@ main(

}

VOID
CopyLoop(
ULARGE_INTEGER FileSize
)
void CopyLoop(ULARGE_INTEGER FileSize)
{
ULARGE_INTEGER ReadPointer;
BOOL Success;
Expand All @@ -388,10 +397,8 @@ CopyLoop(
// Use VirtualAlloc so we get a page-aligned buffer suitable
// for unbuffered I/O.
//
CopyChunk[i].Buffer = VirtualAlloc(NULL,
BUFFER_SIZE,
MEM_COMMIT,
PAGE_READWRITE);
CopyChunk[i].Buffer = malloc(BUFFER_SIZE);

if (CopyChunk[i].Buffer == NULL) {
fprintf(stderr, "VirtualAlloc %d failed, error %d\n",i, GetLastError());
exit(1);
Expand Down Expand Up @@ -434,14 +441,14 @@ CopyLoop(
//
// Either the function failed to dequeue a completion packet
// (CompletedOverlapped is not NULL) or it dequeued a completion
// packet of a failed I/O operation (CompletedOverlapped is NULL).
// packet of a failed I/O operation (CompletedOverlapped is NULL).
//
fprintf(stderr,
"GetQueuedCompletionStatus on the IoPort failed, error %d\n",
GetLastError());
exit(1);
}


Chunk = (PCOPY_CHUNK)CompletedOverlapped;

Expand Down Expand Up @@ -507,7 +514,7 @@ CopyLoop(
}
}
//
// All done. There is no need to call VirtualFree() to free CopyChunk
// All done. There is no need to call VirtualFree() to free CopyChunk
// buffers here. The buffers will be freed when this process exits.
//
}
Loading

0 comments on commit 8e131e8

Please sign in to comment.