1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <assert.h>
21: #include <errno.h>
22: #include <inttypes.h>
23: #include <stdio.h>
24: #include <stdio_ext.h>
25: #include <stdlib.h>
26: #include <string.h>
27: #include <sys/resource.h>
28: #include "pthreadP.h"
29: #include <lowlevellock.h>
30: #include <ldsodefs.h>
31:
32:
33: int
34: pthread_getattr_np (thread_id, attr)
35: pthread_t thread_id;
36: pthread_attr_t *attr;
37: {
38: struct pthread *thread = (struct pthread *) thread_id;
39: struct pthread_attr *iattr = (struct pthread_attr *) attr;
40: int ret = 0;
41:
42: lll_lock (thread->lock, LLL_PRIVATE);
43:
44:
45:
46: memcpy (&iattr->schedparam, &thread->schedparam,
47: sizeof (struct sched_param));
48: iattr->schedpolicy = thread->schedpolicy;
49:
50:
51: iattr->flags = thread->flags;
52:
53:
54: if (IS_DETACHED (thread))
55: iattr->flags |= ATTR_FLAG_DETACHSTATE;
56:
57:
58: iattr->guardsize = thread->reported_guardsize;
59:
60:
61: if (__builtin_expect (thread->stackblock != NULL, 1))
62: {
63: iattr->stacksize = thread->stackblock_size;
64: iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize;
65: }
66: else
67: {
68:
69:
70: assert (abs (thread->pid) == thread->tid);
71:
72:
73: struct rlimit rl;
74:
75:
76:
77:
78: FILE *fp = fopen ("/proc/self/maps", "rc");
79: if (fp == NULL)
80: ret = errno;
81:
82: else
83: {
84: if (getrlimit (RLIMIT_STACK, &rl) != 0)
85: ret = errno;
86: else
87: {
88:
89: __fsetlocking (fp, FSETLOCKING_BYCALLER);
90:
91:
92:
93: ret = ENOENT;
94:
95: char *line = NULL;
96: size_t linelen = 0;
97: uintptr_t last_to = 0;
98:
99: while (! feof_unlocked (fp))
100: {
101: if (__getdelim (&line, &linelen, '\n', fp) <= 0)
102: break;
103:
104: uintptr_t from;
105: uintptr_t to;
106: if (sscanf (line, "%" SCNxPTR "-%" SCNxPTR, &from, &to) != 2)
107: continue;
108: if (from <= (uintptr_t) __libc_stack_end
109: && (uintptr_t) __libc_stack_end < to)
110: {
111:
112: iattr->stacksize = rl.rlim_cur;
113: iattr->stackaddr = (void *) to;
114:
115:
116: if ((size_t) iattr->stacksize
117: > (size_t) iattr->stackaddr - last_to)
118: iattr->stacksize = (size_t) iattr->stackaddr - last_to;
119:
120:
121: ret = 0;
122: break;
123: }
124: last_to = to;
125: }
126:
127: free (line);
128: }
129:
130: fclose (fp);
131: }
132: }
133:
134: iattr->flags |= ATTR_FLAG_STACKADDR;
135:
136: if (ret == 0)
137: {
138: size_t size = 16;
139: cpu_set_t *cpuset = NULL;
140:
141: do
142: {
143: size <<= 1;
144:
145: void *newp = realloc (cpuset, size);
146: if (newp == NULL)
147: {
148: ret = ENOMEM;
149: break;
150: }
151: cpuset = (cpu_set_t *) newp;
152:
153: ret = __pthread_getaffinity_np (thread_id, size, cpuset);
154: }
155:
156: while (ret == EINVAL && size < 1024 * 1024);
157:
158: if (ret == 0)
159: {
160: iattr->cpuset = cpuset;
161: iattr->cpusetsize = size;
162: }
163: else
164: {
165: free (cpuset);
166: if (ret == ENOSYS)
167: {
168:
169: ret = 0;
170: iattr->cpuset = NULL;
171: iattr->cpusetsize = 0;
172: }
173: }
174: }
175:
176: lll_unlock (thread->lock, LLL_PRIVATE);
177:
178: return ret;
179: }