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

View File

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

View File

@ -28,12 +28,12 @@
#include "../cpu.h" // CAS #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); 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; return (pthread_t)(uintptr_t)h;
} }
@ -47,7 +47,7 @@ static pthread_t HANDLE_to_pthread_t(HANDLE h)
pthread_t pthread_self(void) 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) if(param)
{ {
const HANDLE hThread = pthread_t_to_HANDLE(thread); const HANDLE hThread = HANDLE_from_pthread(thread);
param->sched_priority = GetThreadPriority(hThread); 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); SetPriorityClass(GetCurrentProcess(), pri_class);
// choose fixed Windows values from pri // choose fixed Windows values from pri
const HANDLE hThread = pthread_t_to_HANDLE(thread); const HANDLE hThread = HANDLE_from_pthread(thread);
SetThreadPriority(hThread, pri); SetThreadPriority(hThread, pri);
return 0; return 0;
} }
@ -128,18 +128,20 @@ int pthread_key_create(pthread_key_t* key, void (*dtor)(void*))
debug_assert(idx < TLS_LIMIT); debug_assert(idx < TLS_LIMIT);
*key = (pthread_key_t)idx; *key = (pthread_key_t)idx;
// store dtor // acquire a free dtor slot
for(uint i = 0; i < MAX_DTORS; i++) for(uint i = 0; i < MAX_DTORS; i++)
// .. successfully acquired the slot {
if(CAS(&dtors[i].dtor, 0, dtor)) if(CAS(&dtors[i].dtor, 0, dtor))
{ goto have_slot;
dtors[i].key = *key; }
return 0;
}
// not enough slots; we have a valid key, but its dtor won't be called. // not enough slots; we have a valid key, but its dtor won't be called.
debug_warn("increase pthread MAX_DTORS"); debug_warn("increase pthread MAX_DTORS");
return -1; return -1;
have_slot:
dtors[i].key = *key;
return 0;
} }
@ -229,51 +231,50 @@ again:
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// POD (allocated via malloc - see below) // _beginthreadex cannot call the user's thread function directly due to
struct ThreadFunc // 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*(*func)(void*);
void* user_arg; void* arg;
}; }
func_and_arg;
// trampoline to switch calling convention. // bridge calling conventions required by _beginthreadex and POSIX.
// param points to a heap-allocated ThreadFunc (see pthread_create).
static unsigned __stdcall thread_start(void* param) static unsigned __stdcall thread_start(void* param)
{ {
ThreadFunc* f = (ThreadFunc*)param; void*(*func)(void*) = func_and_arg.func;
void*(*func)(void*) = f->func; void* arg = func_and_arg.arg;
void* user_arg = f->user_arg; win_unlock(WPTHREAD_CS);
free(f);
// workaround for stupid "void* -> unsigned cast" warning void* ret = func(arg);
union { void* p; unsigned u; } v;
v.p = func(user_arg);
call_tls_dtors(); 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. win_lock(WPTHREAD_CS);
// note: don't stack-allocate this, since the new thread might func_and_arg.func = func;
// not be executed before we tear down our stack frame. func_and_arg.arg = arg;
ThreadFunc* const f = (ThreadFunc*)malloc(sizeof(ThreadFunc));
if(!f)
return -EAGAIN; // SUSv3
f->func = func;
f->user_arg = user_arg;
// _beginthreadex has more overhead and no value added vs. // _beginthreadex has more overhead and no value added vs.
// CreateThread, but it avoids small memory leaks in // CreateThread, but it avoids small memory leaks in
// ExitThread when using the statically-linked CRT (-> MSDN). // 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) if(!id)
{ {
free(f); win_unlock(WPTHREAD_CS);
debug_warn("_beginthreadex failed"); debug_warn("_beginthreadex failed");
return -1; 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) int pthread_cancel(pthread_t thread)
{ {
HANDLE hThread = pthread_t_to_HANDLE(thread); HANDLE hThread = HANDLE_from_pthread(thread);
TerminateThread(hThread, 0); TerminateThread(hThread, 0);
debug_printf("WARNING: pthread_cancel is unsafe\n"); debug_printf("WARNING: pthread_cancel is unsafe\n");
return 0; return 0;
@ -297,7 +298,7 @@ int pthread_cancel(pthread_t thread)
int pthread_join(pthread_t thread, void** value_ptr) 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 // 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. // 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; const DWORD dwFlags = PFD_SUPPORT_OPENGL|PFD_DRAW_TO_WINDOW|PFD_DOUBLEBUFFER;
BYTE cColorBits = (BYTE)bpp; BYTE cColourBits = (BYTE)bpp;
BYTE cAlphaBits = 0; BYTE cAlphaBits = 0;
if(bpp == 32) if(bpp == 32)
{ {
cColorBits = 24; cColourBits = 24;
cAlphaBits = 8; cAlphaBits = 8;
} }
const BYTE cAccumBits = 0; const BYTE cAccumBits = 0;
@ -705,7 +705,7 @@ keep:
1, // version 1, // version
dwFlags, dwFlags,
PFD_TYPE_RGBA, 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 cAlphaBits, 0, // cAlphaShift is unused
cAccumBits, 0, 0, 0, 0, // cAccum*Bits are unused cAccumBits, 0, 0, 0, 0, // cAccum*Bits are unused
cDepthBits, cDepthBits,