view dmd/root/async.c @ 1346:6f4154b318ef

Remove an old workaround that was kept around for ABI-compatibility on x86-64 between different LLVM versions. This means LLVM r67588 is required if you want to compile for x86-64, otherwise the backend will assert when you try to return e.g. struct { int i; char c; } from a function. (In particular, this is no longer compatible with LLVM 2.5) It also means that any code returning small structs on x86-64 will probably need to be recompiled in order to be linkable to code compiled with this change.
author Frits van Bommel <fvbommel wxs.nl>
date Tue, 12 May 2009 15:50:48 +0200
parents e961851fb8be
children def7a1d494fd
line wrap: on
line source


#define _MT 1

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#if _WIN32

#include <windows.h>
#include <stdio.h>
#include <errno.h>
#include <process.h>

#include "root.h"
#include "rmem.h"

static unsigned __stdcall startthread(void *p);

struct FileData
{
    File *file;
    int result;
    HANDLE event;
};

struct AsyncRead
{
    static AsyncRead *create(size_t nfiles);
    void addFile(File *file);
    void start();
    int read(size_t i);
    static void dispose(AsyncRead *);

    HANDLE hThread;

    size_t filesdim;
    size_t filesmax;
    FileData files[1];
};


AsyncRead *AsyncRead::create(size_t nfiles)
{
    AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
				(nfiles - 1) * sizeof(FileData));
    aw->filesmax = nfiles;
    return aw;
}

void AsyncRead::addFile(File *file)
{
    //printf("addFile(file = %p)\n", file);
    //printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
    assert(filesdim < filesmax);
    files[filesdim].file = file;
    files[filesdim].event = CreateEvent(NULL, TRUE, FALSE, NULL);
    ResetEvent(files[filesdim].event);
    filesdim++;
}

void AsyncRead::start()
{
    unsigned threadaddr;
    hThread = (HANDLE) _beginthreadex(NULL,
	0,
	&startthread,
	this,
	0,
	(unsigned *)&threadaddr);

    if (hThread)
    {
	SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
    }
    else
    {
	assert(0);
    }
}

int AsyncRead::read(size_t i)
{
    FileData *f = &files[i];
    WaitForSingleObject(f->event, INFINITE);
    Sleep(0);			// give up time slice
    return f->result;
}

void AsyncRead::dispose(AsyncRead *aw)
{
    delete aw;
}



unsigned __stdcall startthread(void *p)
{
    AsyncRead *aw = (AsyncRead *)p;

    for (size_t i = 0; i < aw->filesdim; i++)
    {	FileData *f = &aw->files[i];

	f->result = f->file->read();
	SetEvent(f->event);
    }
    _endthreadex(EXIT_SUCCESS);
    return EXIT_SUCCESS;		// if skidding
}

#else

#include <stdio.h>
#include <errno.h>

#include "root.h"
#include "rmem.h"

struct FileData
{
    File *file;
    int result;
    //HANDLE event;
};

struct AsyncRead
{
    static AsyncRead *create(size_t nfiles);
    void addFile(File *file);
    void start();
    int read(size_t i);
    static void dispose(AsyncRead *);

    //HANDLE hThread;

    size_t filesdim;
    size_t filesmax;
    FileData files[1];
};


AsyncRead *AsyncRead::create(size_t nfiles)
{
    AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
				(nfiles - 1) * sizeof(FileData));
    aw->filesmax = nfiles;
    return aw;
}

void AsyncRead::addFile(File *file)
{
    //printf("addFile(file = %p)\n", file);
    //printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
    assert(filesdim < filesmax);
    files[filesdim].file = file;
    //files[filesdim].event = CreateEvent(NULL, TRUE, FALSE, NULL);
    //ResetEvent(files[filesdim].event);
    filesdim++;
}

void AsyncRead::start()
{
}

int AsyncRead::read(size_t i)
{
    FileData *f = &files[i];
    f->result = f->file->read();
    return f->result;
}

void AsyncRead::dispose(AsyncRead *aw)
{
    delete aw;
}

#endif