mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-19 14:23:13 +01:00
Merge dmd-1.074 into ldc.
This commit is contained in:
650
dmd/root/async.c
650
dmd/root/async.c
@@ -1,325 +1,325 @@
|
||||
|
||||
#define _MT 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "root.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 *)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()
|
||||
{
|
||||
//printf("aw->filesdim = %p %d\n", this, filesdim);
|
||||
if (filesdim)
|
||||
{
|
||||
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)
|
||||
{
|
||||
free(aw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned __stdcall startthread(void *p)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)p;
|
||||
|
||||
//printf("aw->filesdim = %p %d\n", aw, aw->filesdim);
|
||||
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
|
||||
}
|
||||
|
||||
#elif linux // Posix
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "root.h"
|
||||
|
||||
void *startthread(void *arg);
|
||||
|
||||
void err_abort(int status, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "fatal error = %d, %s\n", status, msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct FileData
|
||||
{
|
||||
File *file;
|
||||
int result;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct AsyncRead
|
||||
{
|
||||
static AsyncRead *create(size_t nfiles);
|
||||
void addFile(File *file);
|
||||
void start();
|
||||
int read(size_t i);
|
||||
static void dispose(AsyncRead *);
|
||||
|
||||
size_t filesdim;
|
||||
size_t filesmax;
|
||||
FileData files[1];
|
||||
};
|
||||
|
||||
|
||||
AsyncRead *AsyncRead::create(size_t nfiles)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)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);
|
||||
FileData *f = &files[filesdim];
|
||||
f->file = file;
|
||||
|
||||
int status = pthread_mutex_init(&f->mutex, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "init mutex");
|
||||
status = pthread_cond_init(&f->cond, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "init cond");
|
||||
|
||||
filesdim++;
|
||||
}
|
||||
|
||||
void AsyncRead::start()
|
||||
{
|
||||
//printf("aw->filesdim = %p %d\n", this, filesdim);
|
||||
if (filesdim)
|
||||
{
|
||||
pthread_t thread_id;
|
||||
int status = pthread_create(&thread_id,
|
||||
NULL,
|
||||
&startthread,
|
||||
this);
|
||||
if (status != 0)
|
||||
err_abort(status, "create thread");
|
||||
}
|
||||
}
|
||||
|
||||
int AsyncRead::read(size_t i)
|
||||
{
|
||||
FileData *f = &files[i];
|
||||
|
||||
// Wait for the event
|
||||
int status = pthread_mutex_lock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "lock mutex");
|
||||
while (f->value == 0)
|
||||
{
|
||||
status = pthread_cond_wait(&f->cond, &f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "wait on condition");
|
||||
}
|
||||
status = pthread_mutex_unlock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "unlock mutex");
|
||||
|
||||
return f->result;
|
||||
}
|
||||
|
||||
void AsyncRead::dispose(AsyncRead *aw)
|
||||
{
|
||||
//printf("AsyncRead::dispose()\n");
|
||||
for (int i = 0; i < aw->filesdim; i++)
|
||||
{
|
||||
FileData *f = &aw->files[i];
|
||||
int status = pthread_cond_destroy(&f->cond);
|
||||
if (status != 0)
|
||||
err_abort(status, "cond destroy");
|
||||
status = pthread_mutex_destroy(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "mutex destroy");
|
||||
}
|
||||
free(aw);
|
||||
}
|
||||
|
||||
|
||||
void *startthread(void *p)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)p;
|
||||
|
||||
//printf("startthread: aw->filesdim = %p %d\n", aw, aw->filesdim);
|
||||
size_t dim = aw->filesdim;
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ FileData *f = &aw->files[i];
|
||||
|
||||
f->result = f->file->read();
|
||||
|
||||
// Set event
|
||||
int status = pthread_mutex_lock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "lock mutex");
|
||||
f->value = 1;
|
||||
status = pthread_cond_signal(&f->cond);
|
||||
if (status != 0)
|
||||
err_abort(status, "signal condition");
|
||||
status = pthread_mutex_unlock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "unlock mutex");
|
||||
}
|
||||
|
||||
return NULL; // end thread
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "root.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 *)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)
|
||||
{
|
||||
free(aw);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define _MT 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "root.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 *)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()
|
||||
{
|
||||
//printf("aw->filesdim = %p %d\n", this, filesdim);
|
||||
if (filesdim)
|
||||
{
|
||||
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)
|
||||
{
|
||||
free(aw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned __stdcall startthread(void *p)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)p;
|
||||
|
||||
//printf("aw->filesdim = %p %d\n", aw, aw->filesdim);
|
||||
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
|
||||
}
|
||||
|
||||
#elif linux // Posix
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "root.h"
|
||||
|
||||
void *startthread(void *arg);
|
||||
|
||||
void err_abort(int status, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "fatal error = %d, %s\n", status, msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct FileData
|
||||
{
|
||||
File *file;
|
||||
int result;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct AsyncRead
|
||||
{
|
||||
static AsyncRead *create(size_t nfiles);
|
||||
void addFile(File *file);
|
||||
void start();
|
||||
int read(size_t i);
|
||||
static void dispose(AsyncRead *);
|
||||
|
||||
size_t filesdim;
|
||||
size_t filesmax;
|
||||
FileData files[1];
|
||||
};
|
||||
|
||||
|
||||
AsyncRead *AsyncRead::create(size_t nfiles)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)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);
|
||||
FileData *f = &files[filesdim];
|
||||
f->file = file;
|
||||
|
||||
int status = pthread_mutex_init(&f->mutex, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "init mutex");
|
||||
status = pthread_cond_init(&f->cond, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "init cond");
|
||||
|
||||
filesdim++;
|
||||
}
|
||||
|
||||
void AsyncRead::start()
|
||||
{
|
||||
//printf("aw->filesdim = %p %d\n", this, filesdim);
|
||||
if (filesdim)
|
||||
{
|
||||
pthread_t thread_id;
|
||||
int status = pthread_create(&thread_id,
|
||||
NULL,
|
||||
&startthread,
|
||||
this);
|
||||
if (status != 0)
|
||||
err_abort(status, "create thread");
|
||||
}
|
||||
}
|
||||
|
||||
int AsyncRead::read(size_t i)
|
||||
{
|
||||
FileData *f = &files[i];
|
||||
|
||||
// Wait for the event
|
||||
int status = pthread_mutex_lock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "lock mutex");
|
||||
while (f->value == 0)
|
||||
{
|
||||
status = pthread_cond_wait(&f->cond, &f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "wait on condition");
|
||||
}
|
||||
status = pthread_mutex_unlock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "unlock mutex");
|
||||
|
||||
return f->result;
|
||||
}
|
||||
|
||||
void AsyncRead::dispose(AsyncRead *aw)
|
||||
{
|
||||
//printf("AsyncRead::dispose()\n");
|
||||
for (int i = 0; i < aw->filesdim; i++)
|
||||
{
|
||||
FileData *f = &aw->files[i];
|
||||
int status = pthread_cond_destroy(&f->cond);
|
||||
if (status != 0)
|
||||
err_abort(status, "cond destroy");
|
||||
status = pthread_mutex_destroy(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "mutex destroy");
|
||||
}
|
||||
free(aw);
|
||||
}
|
||||
|
||||
|
||||
void *startthread(void *p)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)p;
|
||||
|
||||
//printf("startthread: aw->filesdim = %p %d\n", aw, aw->filesdim);
|
||||
size_t dim = aw->filesdim;
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ FileData *f = &aw->files[i];
|
||||
|
||||
f->result = f->file->read();
|
||||
|
||||
// Set event
|
||||
int status = pthread_mutex_lock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "lock mutex");
|
||||
f->value = 1;
|
||||
status = pthread_cond_signal(&f->cond);
|
||||
if (status != 0)
|
||||
err_abort(status, "signal condition");
|
||||
status = pthread_mutex_unlock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "unlock mutex");
|
||||
}
|
||||
|
||||
return NULL; // end thread
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "root.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 *)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)
|
||||
{
|
||||
free(aw);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user