1
0
forked from 0ad/0ad

wpthread: improved code and avoid memory alloc during thread creation

wsdl and tex: use british english terms

This was SVN commit r2594.
This commit is contained in:
janwas 2005-08-10 00:33:15 +00:00
parent 4b33f49da1
commit ff97a903b8
4 changed files with 71 additions and 69 deletions

View File

@ -518,8 +518,8 @@ static int dds_encode(TexInfo* UNUSED(t), const char* UNUSED(fn), u8* UNUSED(img
enum TgaImgType
{
TGA_TRUE_COLOR = 2, // uncompressed 24 or 32 bit direct RGB
TGA_GREY = 3 // uncompressed 8 bit direct greyscale
TGA_TRUE_COLOUR = 2, // uncompressed 24 or 32 bit direct RGB
TGA_GREY = 3 // uncompressed 8 bit direct greyscale
};
enum TgaImgDesc
@ -532,9 +532,9 @@ enum TgaImgDesc
typedef struct
{
u8 img_id_len; // 0 - no image identifier present
u8 color_map_type; // 0 - no color map present
u8 colour_map_type; // 0 - no colour map present
u8 img_type; // see TgaImgType
u8 color_map[5]; // unused
u8 colour_map[5]; // unused
u16 x_origin; // unused
u16 y_origin; // unused
@ -547,7 +547,7 @@ typedef struct
}
TgaHeader;
// TGA file: header [img id] [color map] image data
// TGA file: header [img id] [colour map] image data
#pragma pack(pop)
@ -561,12 +561,12 @@ static inline bool tga_fmt(const u8* ptr, size_t size)
TgaHeader* hdr = (TgaHeader*)ptr;
// not direct color
if(hdr->color_map_type != 0)
// not direct colour
if(hdr->colour_map_type != 0)
return false;
// wrong color type (not uncompressed greyscale or RGB)
if(hdr->img_type != TGA_TRUE_COLOR && hdr->img_type != TGA_GREY)
// wrong colour type (not uncompressed greyscale or RGB)
if(hdr->img_type != TGA_TRUE_COLOUR && hdr->img_type != TGA_GREY)
return false;
return true;
@ -579,7 +579,7 @@ static inline bool tga_ext(const char* ext)
}
// requirements: uncompressed, direct color, bottom up
// requirements: uncompressed, direct colour, bottom up
static int tga_decode(TexInfo* t, const char* fn, u8* file, size_t file_size)
{
const char* err = 0;
@ -613,7 +613,7 @@ fail:
flags |= TEX_ALPHA;
if(bpp == 8)
flags |= TEX_GREY;
if(type == TGA_TRUE_COLOR)
if(type == TGA_TRUE_COLOUR)
flags |= TEX_BGR;
// storing right-to-left is just stupid;
@ -648,7 +648,7 @@ static int tga_encode(TexInfo* t, const char* fn, u8* img, size_t img_size)
u8 img_desc = (t->flags & TEX_TOP_DOWN)? TGA_TOP_DOWN : TGA_BOTTOM_UP;
if(t->bpp == 32)
img_desc |= 8; // size of alpha channel
TgaImgType img_type = (t->flags & TEX_GREY)? TGA_GREY : TGA_TRUE_COLOR;
TgaImgType img_type = (t->flags & TEX_GREY)? TGA_GREY : TGA_TRUE_COLOUR;
// transform
int transforms = t->flags;
@ -659,9 +659,9 @@ static int tga_encode(TexInfo* t, const char* fn, u8* img, size_t img_size)
TgaHeader hdr =
{
0, // no image identifier present
0, // no color map present
0, // no colour map present
(u8)img_type,
{0,0,0,0,0}, // unused (color map)
{0,0,0,0,0}, // unused (colour map)
0, 0, // unused (origin)
t->w,
t->h,
@ -737,7 +737,7 @@ static inline bool bmp_ext(const char* ext)
}
// requirements: uncompressed, direct color, bottom up
// requirements: uncompressed, direct colour, bottom up
static int bmp_decode(TexInfo* t, const char* fn, u8* file, size_t file_size)
{
const char* err = 0;
@ -774,7 +774,7 @@ fail:
if(compress != BI_RGB)
err = "compressed";
if(bpp != 24 && bpp != 32)
err = "invalid bpp (not direct color)";
err = "invalid bpp (not direct colour)";
if(file_size < ofs+img_size)
err = "image not completely read";
if(err)
@ -858,7 +858,7 @@ static int raw_decode(TexInfo* t, const char* fn, u8* file, size_t file_size)
{
// TODO: allow 8 bit format. problem: how to differentiate from 32? filename?
// find a color depth that matches file_size
// find a colour depth that matches file_size
uint i, dim;
for(i = 2; i <= 4; i++)
{
@ -968,8 +968,8 @@ static int png_decode_impl(TexInfo* t, u8* file, size_t file_size,
// read header and determine format
png_read_info(png_ptr, info_ptr);
png_uint_32 w, h;
int bit_depth, color_type;
png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
int bit_depth, colour_type;
png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &colour_type, 0, 0, 0);
const size_t pitch = png_get_rowbytes(png_ptr, info_ptr);
const u32 bpp = (u32)(pitch / w * 8);
@ -980,8 +980,8 @@ static int png_decode_impl(TexInfo* t, u8* file, size_t file_size,
// make sure format is acceptable
if(bit_depth != 8)
msg = "channel precision != 8 bits";
if(color_type & PNG_COLOR_MASK_PALETTE)
msg = "color type is invalid (must be direct color)";
if(colour_type & PNG_COLOR_MASK_PALETTE)
msg = "colour type is invalid (must be direct colour)";
if(msg)
return -1;
@ -1095,20 +1095,20 @@ static int png_encode_impl(TexInfo* t, const char* fn, u8* img,
const png_uint_32 w = t->w, h = t->h;
const size_t pitch = w * t->bpp / 8;
int color_type;
int colour_type;
switch(t->flags & (TEX_GREY|TEX_ALPHA))
{
case TEX_GREY|TEX_ALPHA:
color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
break;
case TEX_GREY:
color_type = PNG_COLOR_TYPE_GRAY;
colour_type = PNG_COLOR_TYPE_GRAY;
break;
case TEX_ALPHA:
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
break;
default:
color_type = PNG_COLOR_TYPE_RGB;
colour_type = PNG_COLOR_TYPE_RGB;
break;
}
@ -1116,7 +1116,7 @@ static int png_encode_impl(TexInfo* t, const char* fn, u8* img,
CHECK_ERR(hf);
png_set_write_fn(png_ptr, &hf, png_write, png_flush);
png_set_IHDR(png_ptr, info_ptr, w, h, 8, color_type,
png_set_IHDR(png_ptr, info_ptr, w, h, 8, colour_type,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
const int transforms = TEX_TOP_DOWN ^ t->flags;
@ -1418,7 +1418,7 @@ fail:
int bpp = cinfo.num_components * 8;
// preliminary; set below to reflect output params
// make sure we get a color format we know
// make sure we get a colour format we know
// (exception: if bpp = 8, go greyscale below)
// necessary to support non-standard CMYK files written by Photoshop.
cinfo.out_color_space = JCS_RGB;

View File

@ -391,6 +391,7 @@ enum
WAIO_CS,
WIN_CS,
WDBG_CS,
WPTHREAD_CS,
NUM_CS
};

View File

@ -28,12 +28,12 @@
#include "../cpu.h" // CAS
static HANDLE pthread_t_to_HANDLE(pthread_t p)
static HANDLE HANDLE_from_pthread(pthread_t p)
{
return (HANDLE)((char*)0 + p);
}
static pthread_t HANDLE_to_pthread_t(HANDLE h)
static pthread_t pthread_from_HANDLE(HANDLE h)
{
return (pthread_t)(uintptr_t)h;
}
@ -47,7 +47,7 @@ static pthread_t HANDLE_to_pthread_t(HANDLE h)
pthread_t pthread_self(void)
{
return HANDLE_to_pthread_t(GetCurrentThread());
return pthread_from_HANDLE(GetCurrentThread());
}
@ -68,7 +68,7 @@ int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* par
}
if(param)
{
const HANDLE hThread = pthread_t_to_HANDLE(thread);
const HANDLE hThread = HANDLE_from_pthread(thread);
param->sched_priority = GetThreadPriority(hThread);
}
@ -90,7 +90,7 @@ int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param
SetPriorityClass(GetCurrentProcess(), pri_class);
// choose fixed Windows values from pri
const HANDLE hThread = pthread_t_to_HANDLE(thread);
const HANDLE hThread = HANDLE_from_pthread(thread);
SetThreadPriority(hThread, pri);
return 0;
}
@ -128,18 +128,20 @@ int pthread_key_create(pthread_key_t* key, void (*dtor)(void*))
debug_assert(idx < TLS_LIMIT);
*key = (pthread_key_t)idx;
// store dtor
// acquire a free dtor slot
for(uint i = 0; i < MAX_DTORS; i++)
// .. successfully acquired the slot
{
if(CAS(&dtors[i].dtor, 0, dtor))
{
dtors[i].key = *key;
return 0;
}
goto have_slot;
}
// not enough slots; we have a valid key, but its dtor won't be called.
debug_warn("increase pthread MAX_DTORS");
return -1;
have_slot:
dtors[i].key = *key;
return 0;
}
@ -229,51 +231,50 @@ again:
//
//////////////////////////////////////////////////////////////////////////////
// POD (allocated via malloc - see below)
struct ThreadFunc
// _beginthreadex cannot call the user's thread function directly due to
// differences in calling convention; we need to pass its address and
// the user-specified data pointer to our trampoline.
// a) a local variable in pthread_create isn't safe because the
// new thread might not start before pthread_create returns.
// b) allocating on the heap would work but we're trying to keep that
// to a minimum.
// c) we therefore use static data protected by a critical section.
static struct FuncAndArg
{
void*(*func)(void*);
void* user_arg;
};
void* arg;
}
func_and_arg;
// trampoline to switch calling convention.
// param points to a heap-allocated ThreadFunc (see pthread_create).
// bridge calling conventions required by _beginthreadex and POSIX.
static unsigned __stdcall thread_start(void* param)
{
ThreadFunc* f = (ThreadFunc*)param;
void*(*func)(void*) = f->func;
void* user_arg = f->user_arg;
free(f);
void*(*func)(void*) = func_and_arg.func;
void* arg = func_and_arg.arg;
win_unlock(WPTHREAD_CS);
// workaround for stupid "void* -> unsigned cast" warning
union { void* p; unsigned u; } v;
v.p = func(user_arg);
void* ret = func(arg);
call_tls_dtors();
return v.u;
return (unsigned)(uintptr_t)ret;
}
int pthread_create(pthread_t* thread_id, const void* UNUSED(attr), void*(*func)(void*), void* user_arg)
int pthread_create(pthread_t* thread_id, const void* UNUSED(attr), void*(*func)(void*), void* arg)
{
// tell the trampoline above what to call.
// note: don't stack-allocate this, since the new thread might
// not be executed before we tear down our stack frame.
ThreadFunc* const f = (ThreadFunc*)malloc(sizeof(ThreadFunc));
if(!f)
return -EAGAIN; // SUSv3
f->func = func;
f->user_arg = user_arg;
win_lock(WPTHREAD_CS);
func_and_arg.func = func;
func_and_arg.arg = arg;
// _beginthreadex has more overhead and no value added vs.
// CreateThread, but it avoids small memory leaks in
// ExitThread when using the statically-linked CRT (-> MSDN).
const uintptr_t id = _beginthreadex(0, 0, thread_start, f, 0, 0);
const uintptr_t id = _beginthreadex(0, 0, thread_start, 0, 0, 0);
if(!id)
{
free(f);
win_unlock(WPTHREAD_CS);
debug_warn("_beginthreadex failed");
return -1;
}
@ -288,7 +289,7 @@ int pthread_create(pthread_t* thread_id, const void* UNUSED(attr), void*(*func)(
int pthread_cancel(pthread_t thread)
{
HANDLE hThread = pthread_t_to_HANDLE(thread);
HANDLE hThread = HANDLE_from_pthread(thread);
TerminateThread(hThread, 0);
debug_printf("WARNING: pthread_cancel is unsafe\n");
return 0;
@ -297,7 +298,7 @@ int pthread_cancel(pthread_t thread)
int pthread_join(pthread_t thread, void** value_ptr)
{
HANDLE hThread = pthread_t_to_HANDLE(thread);
HANDLE hThread = HANDLE_from_pthread(thread);
// note: pthread_join doesn't call for a timeout. if this wait
// locks up the process, at least it'll be easy to see why.

View File

@ -687,11 +687,11 @@ keep:
//
const DWORD dwFlags = PFD_SUPPORT_OPENGL|PFD_DRAW_TO_WINDOW|PFD_DOUBLEBUFFER;
BYTE cColorBits = (BYTE)bpp;
BYTE cColourBits = (BYTE)bpp;
BYTE cAlphaBits = 0;
if(bpp == 32)
{
cColorBits = 24;
cColourBits = 24;
cAlphaBits = 8;
}
const BYTE cAccumBits = 0;
@ -705,7 +705,7 @@ keep:
1, // version
dwFlags,
PFD_TYPE_RGBA,
cColorBits, 0, 0, 0, 0, 0, 0, // c*Bits, c*Shift are unused
cColourBits, 0, 0, 0, 0, 0, 0, // c*Bits, c*Shift are unused
cAlphaBits, 0, // cAlphaShift is unused
cAccumBits, 0, 0, 0, 0, // cAccum*Bits are unused
cDepthBits,