少年修仙传客户端基础资源
hch
2024-04-01 d01413b00ef631ac20347716b23818b0b811f65f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
 
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
 
#ifndef GC_THREADS
# define GC_THREADS
#endif
 
#define GC_NO_THREAD_REDIRECTS 1
 
#include "gc.h"
 
#include <stdio.h>
#include <stdlib.h>
 
#if (!defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \
     || defined(__native_client__)) && !defined(SKIP_THREADKEY_TEST)
  /* FIXME: Skip this test on Solaris for now.  The test may fail on    */
  /* other targets as well.  Currently, tested only on Linux, Cygwin    */
  /* and Darwin.                                                        */
# define SKIP_THREADKEY_TEST
#endif
 
#ifdef SKIP_THREADKEY_TEST
 
int main (void)
{
  printf("threadkey_test skipped\n");
  return 0;
}
 
#else
 
#include <pthread.h>
 
pthread_key_t key;
 
#ifdef GC_SOLARIS_THREADS
  /* pthread_once_t key_once = { PTHREAD_ONCE_INIT }; */
#else
  pthread_once_t key_once = PTHREAD_ONCE_INIT;
#endif
 
void * entry (void *arg)
{
  pthread_setspecific(key,
                      (void *)GC_HIDE_POINTER(GC_STRDUP("hello, world")));
  return arg;
}
 
void * GC_CALLBACK on_thread_exit_inner (struct GC_stack_base * sb, void * arg)
{
  int res = GC_register_my_thread (sb);
  pthread_t t;
  int creation_res;     /* Used to suppress a warning about     */
                        /* unchecked pthread_create() result.   */
  pthread_attr_t attr;
 
  if (pthread_attr_init(&attr) != 0
      || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) {
    fprintf(stderr, "Thread attribute init or setdetachstate failed\n");
    exit(2);
  }
  creation_res = GC_pthread_create(&t, &attr, entry, NULL);
  (void)pthread_attr_destroy(&attr);
  if (res == GC_SUCCESS)
    GC_unregister_my_thread ();
 
  return arg ? (void*)(GC_word)creation_res : 0;
}
 
void on_thread_exit (void *v)
{
  GC_call_with_stack_base (on_thread_exit_inner, v);
}
 
void make_key (void)
{
  pthread_key_create (&key, on_thread_exit);
}
 
#ifndef NTHREADS
# define NTHREADS 30 /* number of initial threads */
#endif
 
int main (void)
{
  int i;
  GC_INIT ();
 
# ifdef GC_SOLARIS_THREADS
    pthread_key_create (&key, on_thread_exit);
# else
    pthread_once (&key_once, make_key);
# endif
  for (i = 0; i < NTHREADS; i++) {
    pthread_t t;
 
    if (GC_pthread_create(&t, NULL, entry, NULL) == 0) {
      void *res;
      int code = (i & 1) != 0 ? GC_pthread_join(t, &res)
                                : GC_pthread_detach(t);
 
      if (code != 0) {
        fprintf(stderr, "Thread %s failed %d\n",
                (i & 1) != 0 ? "join" : "detach", code);
        exit(2);
      }
    }
  }
  return 0;
}
 
#endif /* !SKIP_THREADKEY_TEST */