synchronized-counter.m 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // TEST_CONFIG
  2. #include "test.h"
  3. #include <stdlib.h>
  4. #include <pthread.h>
  5. #include <objc/runtime.h>
  6. #include <objc/objc-sync.h>
  7. #include <Foundation/NSObject.h>
  8. #include <System/pthread_machdep.h>
  9. // synchronized stress test
  10. // Single locked counter incremented by many threads.
  11. #if defined(__arm__)
  12. #define THREADS 16
  13. #define COUNT 1024*24
  14. #else
  15. // 64 / 1024*24 test takes about 20s on 4x2.6GHz Mac Pro
  16. #define THREADS 64
  17. #define COUNT 1024*24
  18. #endif
  19. static id lock;
  20. static int count;
  21. static void *threadfn(void *arg)
  22. {
  23. int n, d;
  24. int depth = 1 + (int)(intptr_t)arg % 4;
  25. for (n = 0; n < COUNT; n++) {
  26. // Lock
  27. for (d = 0; d < depth; d++) {
  28. int err = objc_sync_enter(lock);
  29. testassert(err == OBJC_SYNC_SUCCESS);
  30. }
  31. // Increment
  32. count++;
  33. // Unlock
  34. for (d = 0; d < depth; d++) {
  35. int err = objc_sync_exit(lock);
  36. testassert(err == OBJC_SYNC_SUCCESS);
  37. }
  38. }
  39. // Verify lack of objc pthread data (should have used sync fast cache)
  40. #ifdef __PTK_FRAMEWORK_OBJC_KEY0
  41. testassert(! pthread_getspecific(__PTK_FRAMEWORK_OBJC_KEY0));
  42. #endif
  43. return NULL;
  44. }
  45. int main()
  46. {
  47. pthread_t threads[THREADS];
  48. int t;
  49. int err;
  50. lock = [[NSObject alloc] init];
  51. // Verify objc pthread data on this thread (from +initialize)
  52. // Worker threads shouldn't have any because of sync fast cache.
  53. #ifdef __PTK_FRAMEWORK_OBJC_KEY0
  54. testassert(pthread_getspecific(__PTK_FRAMEWORK_OBJC_KEY0));
  55. #endif
  56. // Start the threads
  57. for (t = 0; t < THREADS; t++) {
  58. pthread_create(&threads[t], NULL, &threadfn, (void*)(intptr_t)t);
  59. }
  60. // Wait for threads to finish
  61. for (t = 0; t < THREADS; t++) {
  62. pthread_join(threads[t], NULL);
  63. }
  64. // Verify lock: should be available
  65. // Verify count: should be THREADS*COUNT
  66. err = objc_sync_enter(lock);
  67. testassert(err == OBJC_SYNC_SUCCESS);
  68. testassert(count == THREADS*COUNT);
  69. succeed(__FILE__);
  70. }