コア(MIPS 64)プラットフォームスレッドスタック設定エラーのデバッグプロセス
###スレッドテストコード
###コンパイル運転
以下に示すように、デフォルトのスレッドスタックサイズは8192 Kであるが、スタックサイズを64 Kに設定と、実行エラーの戻り値は22となる.
この場合、pthread_を先に確認します.attr_setstacksizeは、エラーを返す説明を以下に示す説明情報を見つけることができるかどうかを示します.説明によれば、サイズ設定はページサイズの倍数でなければならないが、戻りコードが
次に、戻り値22がどのようなエラーに対応しているのか、また、
まとめ:竜芯(MIPS 64)プラットフォーム、スレッドスタックのサイズ設定要求:1.ページサイズ(16 K)の整数倍でなければならない.スレッドスタックの最小値は、このプラットフォームで128 Kと定義されています.
#include
#include
#include
#include
#include
void *thd_fn(void *args)
{
int n = *((int *)args);
printf("this is thread:%d
", n);
while(1)
{
printf("this is thread:%d
", n);
sleep(1);
}
}
int main(int argc, char *argv[])
{
pthread_attr_t attr;
int ret = pthread_attr_init(&attr);
if(ret != 0)
{
perror("pthread_attr_init_err:");
printf("pthread_attr_init_err ret:%d
", ret);
exit(1);
}
size_t default_stack_size = 0;
ret = pthread_attr_getstacksize(&attr, &default_stack_size);
if(ret != 0)
{
perror("pthread attr getstatck size err:");
printf("pthread_attr_getstatck_size err. ret:%d
", ret);
exit(1);
}
printf("the default stack size:%d, %dK
", default_stack_size, default_stack_size/1024);
size_t stack_size = 64*1024;
//size_t stack_size = 128*1024;
ret = pthread_attr_setstacksize(&attr, stack_size);
if(ret != 0)
{
perror("pthread attr setstatck size");
printf("pthread_attr_setstatcksize err, size :%d(%dK). ret:%d
",stack_size, stack_size/1024, ret);
exit(1);
}
int i = 0;
for(; i<10; i++)
{
pthread_t pid;
ret = pthread_create(&pid, &attr, thd_fn, (void *)&i);
if(ret != 0 )
{
perror("pthread err:");
printf("ret:%d
", ret);
}
}
while(1);
return 0;
}
###コンパイル運転
以下に示すように、デフォルトのスレッドスタックサイズは8192 Kであるが、スタックサイズを64 Kに設定と、実行エラーの戻り値は22となる.
$ gcc pthread_test.c -g -o pthread_test -pthread
$ ./pthread_test
the default stack size:8388608, 8192K
pthread attr setstatck size: Success
pthread_attr_setstatcksize err, size :65536(64K). ret:22
この場合、pthread_を先に確認します.attr_setstacksizeは、エラーを返す説明を以下に示す説明情報を見つけることができるかどうかを示します.説明によれば、サイズ設定はページサイズの倍数でなければならないが、戻りコードが
EINVAL
の場合、スタックサイズが最小要求16 K未満であることを示す.getconf PAGESIZE
から,現在のページサイズは16 Kであり,コードに設定されているサイズは64 Kであり,サイズ須ページサイズの倍数という要求に合致し,16 Kの最小値を超えていることが分かる.変なことが起こったら,必ず妖怪がいる.$ man pthread_attr_setstacksize
ERRORS
pthread_attr_setstacksize() can fail with the following error:
EINVAL The stack size is less than PTHREAD_STACK_MIN (16384) bytes.
On some systems, pthread_attr_setstacksize() can fail with the error EINVAL if stacksize is not a multiple of the system page size.
#
$ getconf PAGESIZE
16384
次に、戻り値22がどのようなエラーに対応しているのか、また、
EINVAL
の値がどれだけあるかを説明するしかありません.linuxプラットフォームエラーコードは/usr/include/asm/errno.h
ファイルに定義されています.しかし、grep "EINVAL" asm/errno.h
は結果が出なかった.cat asm/errno.h
を見ると、ファイルasm-generic/errno-base.h
が含まれていることがわかります.実行grep "EINVAL" asm-generic/errno-base.h -rn
は、関連定義./asm-generic/errno-base.h:26:#define EINVAL 22 /* Invalid argument */
を検索した.幸いなことに、この戻り値はman
の説明と一致したばかりですが、man
の中でこのエラーを言ったのは、スタックサイズがPTHREAD_STACK_MIN (16384)
未満だからです.まさかman
が私をだましたのではないでしょうか.疑いの精神(妊娠しないで試してみる)に基づいて、この説明はx86
プラットフォームに対するものだと推測していますが、私が持っているのはMIPS64
プラットフォームです.では、マクロPTHREAD_STACK_MIN
の定義を見てみましょう.grep
大法によって発見されたPTHREAD_STACK_MIN
ここでの定義は131072 128K
である.ふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふふ#
$ cd /usr/include
$ grep "PTHREAD_STACK_MIN" . -rni
./mips64el-linux-gnuabi64/bits/local_lim.h:81:#define PTHREAD_STACK_MIN 131072
./pthread.h:363: minimal size of the block must be PTHREAD_STACK_MIN. */
./pthread.h:374: to be started. This size must never be less than PTHREAD_STACK_MIN
まとめ:竜芯(MIPS 64)プラットフォーム、スレッドスタックのサイズ設定要求:1.ページサイズ(16 K)の整数倍でなければならない.スレッドスタックの最小値は、このプラットフォームで128 Kと定義されています.