tls.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include <u.h>
  2. #include <libc.h>
  3. enum {
  4. Nloop = 1000,
  5. Nproc = 64,
  6. };
  7. extern uintptr_t gettls0(void);
  8. uint64_t table[32];
  9. void
  10. copier(int in, int out, int count)
  11. {
  12. char buf[32];
  13. char buf2[32];
  14. int tlsfd;
  15. int i, n;
  16. uint64_t *ptr;
  17. uint64_t v;
  18. char c;
  19. snprint(buf, sizeof buf, "/proc/%d/tls", getpid());
  20. if((tlsfd = open(buf, ORDWR)) == -1)
  21. goto fail;
  22. srand(getpid());
  23. i = 0;
  24. while(count == -1 || i < count){
  25. ptr = &table[rand()%nelem(table)];
  26. snprint(buf, sizeof buf, "tls 0x%p\n", ptr);
  27. if(pwrite(tlsfd, buf, strlen(buf), 0) != strlen(buf)){
  28. fprint(2, "pid %d: write: %r\n", getpid());
  29. goto fail;
  30. }
  31. if(read(in, &c, 1) != 1)
  32. break;
  33. *ptr = rand();
  34. if((v = gettls0()) != *ptr){
  35. fprint(2, "gettls %p want %p\n", v, *ptr);
  36. goto fail;
  37. }
  38. write(out, &c, 1);
  39. if((n = pread(tlsfd, buf2, sizeof buf2-1, 0)) == -1){
  40. fprint(2, "pid %d: read: %r\n", getpid());
  41. goto fail;
  42. }
  43. buf2[n] = '\0';
  44. if(strcmp(buf, buf2) != 0){
  45. fprint(2, "pid %d: '%s' != '%s'\n", getpid(), buf, buf2);
  46. goto fail;
  47. }
  48. i++;
  49. }
  50. close(tlsfd);
  51. return;
  52. fail:
  53. if(tlsfd != -1)
  54. close(tlsfd);
  55. print("FAIL %d\n", getpid());
  56. exits("FAIL");
  57. return;
  58. }
  59. void
  60. main(void)
  61. {
  62. int tube[2];
  63. int out, in;
  64. int i;
  65. pipe(tube);
  66. out = tube[0];
  67. in = tube[1];
  68. for(i = 0; i < Nproc; i++){
  69. pipe(tube);
  70. switch(rfork(RFPROC|RFMEM|RFFDG)){
  71. case -1:
  72. sysfatal("fork %r");
  73. case 0:
  74. close(tube[1]);
  75. copier(in, tube[0], Nloop);
  76. exits(nil);
  77. default:
  78. close(tube[0]);
  79. in = tube[1];
  80. break;
  81. }
  82. }
  83. write(out, "x", 1);
  84. copier(in, out, Nloop-1);
  85. close(out);
  86. for(i = 0; i < 8; i++)
  87. waitpid();
  88. exits(nil);
  89. }