diff -urN otp_src_R11B-5.orig/erts/emulator/beam/erl_bif_port.c otp_src_R11B-5.portfix/erts/emulator/beam/erl_bif_port.c --- otp_src_R11B-5.orig/erts/emulator/beam/erl_bif_port.c 2007-09-28 18:55:12.000000000 +0900 +++ otp_src_R11B-5.portfix/erts/emulator/beam/erl_bif_port.c 2007-09-28 20:04:53.000000000 +0900 @@ -39,6 +39,8 @@ #include "register.h" #include "external.h" +#include + extern ErlDrvEntry fd_driver_entry; extern ErlDrvEntry vanilla_driver_entry; extern ErlDrvEntry spawn_driver_entry; @@ -153,25 +155,44 @@ return res; } -static byte *erts_port_call_buff; -static Uint erts_port_call_buff_size; /* Reversed logic to make VxWorks happy */ -static int erts_port_call_need_init = 1; +typedef struct +{ + byte *buff; + Uint buff_size; +} erts_port_call_cache_t; + +static pthread_once_t erts_port_call_once = PTHREAD_ONCE_INIT; +static pthread_key_t erts_port_call_key; +static void ensure_buff_init(void) +{ + int r; + r = pthread_key_create(&erts_port_call_key, NULL); + ASSERT( r==0 ); + return; +} + static byte *ensure_buff(Uint size) { - if (erts_port_call_need_init) { - erts_port_call_buff = erts_alloc(ERTS_ALC_T_PORT_CALL_BUF, - (size_t) size); - erts_port_call_buff_size = size; - erts_port_call_need_init = 0; - } else if (erts_port_call_buff_size < size) { - erts_port_call_buff_size = size; - erts_port_call_buff = erts_realloc(ERTS_ALC_T_PORT_CALL_BUF, - (void *) erts_port_call_buff, - (size_t) size); - } - return erts_port_call_buff; + erts_port_call_cache_t* cache; + pthread_once(&erts_port_call_once, &ensure_buff_init); + + cache = pthread_getspecific(erts_port_call_key); + if( cache==NULL ) + { + cache = erts_alloc(ERTS_ALC_T_PORT_CALL_BUF, sizeof(*cache)); + cache->buff = erts_alloc(ERTS_ALC_T_PORT_CALL_BUF, (size_t)size); + cache->buff_size = size; + pthread_setspecific(erts_port_call_key, cache); + } else if ( cache->buff_size < size ) + { + cache->buff_size = size; + cache->buff = erts_realloc(ERTS_ALC_T_PORT_CALL_BUF, + cache->buff, + (size_t) size); + } + return cache->buff; } BIF_RETTYPE port_call_2(BIF_ALIST_2) {