Al Boldi ha scritto:
Giuliano Colla wrote:
BTW could you refresh my memory? What kernel and libc are you running
with?
linux2.6.22/libc2.3.1
Here is threadbug.c which doesn't show any leaks:
Surprise!
I've slightly modified threadbug.c -> threadbug1.c (attached), in order
to have stops at the proper points, and verify leakage more precisely.
Scenario for today platform: kernel 2.4.21 heavily patched by RedHat,
with a lot of 2.6 features - glibc 2.3.2 (patched accordingly), only
512Mb RAM. On this platform I'm forced to use fpc 2.0.4 because of glibc
incompatibility.
It turns out that LD_ASSUME_KERNEL 2.2.5 makes each thread allocate two
blocks, one of 2044k, and one of 4k, while this kernel (like the 2.6.20
I've been using yesterday) allocates one block of 10240k and one of 4k.
Therefore with 999 threads I had to use LD_ASSUME, to remain within
memory limits. No leakage. Virtual memory: 4136k->2052136k->4136k one
run 4116k->2052116k->4116k.
Changed to 199 threads. 2.2.5 no leakage: 4128->411680->4128.
kernel 2.4.21 -- LEAKAGE OF THE SAME AMOUNT AS WITH FPC:
3844k->2042400k->34576k. It failed to deallocate 3 blocks of 10240k and
3 blocks of 4k. Removing printf(".") doesn't make any difference.
To be more precise, comparing with fpc multithread behavior (same
scenario), fpc 2.0.4 seems to leak slightly more: it fails to free one
4k block with kernel 2.2.5 (2752->618356->2756) , and 3*10240k + 13*4k
with 2.4.21 (2472->3076876->33244)
But if I remove the Terminate and WaitFor, and use just Free, then with
2.2.5 the leakage disappears (2760k->xxx->2760k) while with 2.4.21 the
leakage is unchanged.
My tentative conclusions. Either the test is wrong, because the
deallocation is somehow deferred, and an I/O operation also suspends the
deallocation, or Linux threads have a bug. But, considering the results
from the original threadbug.c compared with threadbug1.c, I'm beginning
to be in favor of the first of the two.
More to come, stay tuned!
Giuliano
--
Giuliano Colla
Whenever people agree with me, I always feel I must be wrong (O. Wilde)
// gcc -lpthread -lreadline -ltermcap threadbug1.c -o threadbug1
#include <pthread.h>
#include <stdio.h>
#include <readline/readline.h>
#define NUM_THREADS 199
char *line;
int wait = 0;
int running;
void *threadbug() {
printf(".");
}
main(){
int i;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_t threads[NUM_THREADS];
line = readline("Interactive?");
if (line[0] == 'y') wait = 1; else wait = 0;
running = 1;
while (running) {
printf("\nstarting threads...\n");
sleep(3);
for (i=0;i<NUM_THREADS;i++)
if ( pthread_create(&threads[i],&attr,threadbug,NULL) )
perror("pthread_create");
if (wait) {
line = readline("\nNow?");
if (line[0] == 'h') running = 0;
}
printf("\nfreeing threads...\n");
sleep(3);
for (i=0;i<NUM_THREADS;i++) {
pthread_join(threads[i], NULL);
//printf(".");
}
}
line = readline("\nEnter to terminate");
}