0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <ndrstandard.h>
0037 #include <time.h>
0038 #include <sys/time.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041 #include <stdio.h>
0042 #include <sys/stat.h>
0043 #include <ctype.h>
0044 #include <pthread.h>
0045 #include <nstd_tls.h>
0046
0047 #include "nstdutil.h"
0048 #include "ndebug.h"
0049 #include "userlog.h"
0050 #include <errno.h>
0051 #include <sys/resource.h>
0052 #include <ndrxdiag.h>
0053
0054
0055
0056
0057
0058
0059 exprivate long M_stack_size = EXFAIL;
0060
0061 exprivate MUTEX_LOCKDECL(M_stack_size_lock);
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 expublic void ndrx_platf_diag(char *file, long line, int code, int err, char *msg)
0074 {
0075 switch (code)
0076 {
0077 case NDRX_DIAG_PTHREAD_CREATE:
0078
0079 NDRX_LOG(log_always, "Failed to pthread_create() for %s (%d): %s, at %s:%ld",
0080 msg, errno, strerror(errno), file, line);
0081 userlog("Failed to pthread_create() for %s (%d): %s, at %s:%ld",
0082 msg, errno, strerror(errno), file, line);
0083
0084 if (ENOMEM==err || EINVAL==err)
0085 {
0086 #ifdef EX_OS_AIX
0087 NDRX_LOG(log_always, "Check thread specific resource "
0088 "settings e.g. NDRX_THREADSTACKSIZE. For AIX ulimit -s "
0089 "is setting global stack limit to all threads! Do limit "
0090 "with NDRX_THREADSTACKSIZE", code);
0091 userlog("Check thread specific resource "
0092 "settings e.g. NDRX_THREADSTACKSIZE. For AIX ulimit -s "
0093 "is setting global stack limit to all threads! Do limit "
0094 "with NDRX_THREADSTACKSIZE", code);
0095 #else
0096 NDRX_LOG(log_always, "Check thread specific resource "
0097 "settings e.g. NDRX_THREADSTACKSIZE", code);
0098 userlog("Check thread specific resource settings "
0099 "e.g. NDRX_THREADSTACKSIZE", code);
0100 #endif
0101 }
0102 break;
0103 }
0104 }
0105
0106
0107
0108
0109
0110 expublic long ndrx_platf_stack_get_size(void)
0111 {
0112 struct rlimit limit;
0113 char *p;
0114
0115 if (EXFAIL==M_stack_size)
0116 {
0117
0118 MUTEX_LOCK_V(M_stack_size_lock);
0119
0120 if (EXFAIL==M_stack_size)
0121 {
0122 if (NULL!=(p=getenv(CONF_NDRX_THREADSTACKSIZE)))
0123 {
0124 M_stack_size=atoi(p)*1024;
0125
0126
0127 if (0==M_stack_size)
0128 {
0129 NDRX_LOG(log_info, "Using OS Default new thread stack size...");
0130 }
0131 }
0132 else
0133 {
0134
0135 M_stack_size=NDRX_STACK_MAX;
0136 }
0137
0138
0139 if (M_stack_size < 0)
0140 {
0141 if (EXSUCCEED!=getrlimit (RLIMIT_STACK, &limit))
0142 {
0143 int err = errno;
0144 NDRX_LOG(log_error, "Failed to get stack size: %s", strerror(err));
0145 userlog("Failed to get stack size: %s", strerror(err));
0146 }
0147 else
0148 {
0149 M_stack_size=limit.rlim_cur;
0150
0151 NDRX_LOG(log_info, "Current stack size: %ld, max: %ld",
0152 M_stack_size, (long)limit.rlim_max);
0153 }
0154 }
0155
0156 if (M_stack_size<0)
0157 {
0158 M_stack_size = NDRX_STACK_MAX;
0159 NDRX_LOG(log_warn, "Unlimited stack, setting to %ld bytes",
0160 M_stack_size);
0161 }
0162 }
0163 MUTEX_UNLOCK_V(M_stack_size_lock);
0164 }
0165
0166 out:
0167 return M_stack_size;
0168 }
0169
0170
0171
0172
0173
0174
0175
0176 expublic void ndrx_platf_stack_set(void *pthread_custom_attr)
0177 {
0178 long ssize = ndrx_platf_stack_get_size();
0179 int ret;
0180 pthread_attr_t *pattr = (pthread_attr_t *)pthread_custom_attr;
0181
0182 if (ssize>0)
0183 {
0184 while (EXSUCCEED!=(ret = pthread_attr_setstacksize(pattr, ssize))
0185 && EINVAL==ret
0186 && ssize > 0)
0187 {
0188 ssize /= 2;
0189 }
0190
0191 if (0==ssize)
0192 {
0193 userlog("Error ! failed to set stack value!");
0194 }
0195 }
0196
0197
0198 }
0199
0200