1 /*
   2  * Copyright 2015 SAP AG. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "misc_aix.hpp"
  26 #include "runtime/stubRoutines.hpp"
  27 
  28 #include <pthread.h>
  29 #include <unistd.h>
  30 #include <errno.h>
  31 
  32 void MiscUtils::init_critsect(MiscUtils::critsect_t* cs) {
  33   const int rc = pthread_mutex_init(cs, NULL);
  34   assert0(rc == 0);
  35 }
  36 
  37 void MiscUtils::free_critsect(MiscUtils::critsect_t* cs) {
  38   const int rc = pthread_mutex_destroy(cs);
  39   assert0(rc == 0);
  40 }
  41 
  42 void MiscUtils::enter_critsect(MiscUtils::critsect_t* cs) {
  43   const int rc = pthread_mutex_lock(cs);
  44   assert0(rc == 0);
  45 }
  46 
  47 void MiscUtils::leave_critsect(MiscUtils::critsect_t* cs) {
  48   const int rc = pthread_mutex_unlock(cs);
  49   assert0(rc == 0);
  50 }
  51 
  52 bool MiscUtils::is_readable_pointer(const void* p) {
  53   if (!CanUseSafeFetch32()) {
  54     return true;
  55   }
  56   int* const aligned = (int*) align_size_down((intptr_t)p, 4);
  57   int cafebabe = 0xcafebabe;
  58   int deadbeef = 0xdeadbeef;
  59   return (SafeFetch32(aligned, cafebabe) != cafebabe) ||
  60          (SafeFetch32(aligned, deadbeef) != deadbeef);
  61 }
  62 
  63 const char* MiscUtils::describe_errno(int err_no) {
  64   switch (err_no) {
  65   case E2BIG: return "E2BIG";
  66   case EACCES: return "EACCES";
  67 #ifdef EADDRINUSE
  68   case EADDRINUSE: return "EADDRINUSE";
  69 #endif
  70 #ifdef EADDRNOTAVAIL
  71   case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
  72 #endif
  73 #ifdef EAFNOSUPPORT
  74   case EAFNOSUPPORT: return "EAFNOSUPPORT";
  75 #endif
  76   case EAGAIN: return "EAGAIN";
  77 #ifdef EALREADY
  78   case EALREADY: return "EALREADY";
  79 #endif
  80   case EBADF: return "EBADF";
  81 #ifdef EBADMSG
  82   case EBADMSG: return "EBADMSG";
  83 #endif
  84   case EBUSY: return "EBUSY";
  85 #ifdef ECANCELED
  86   case ECANCELED: return "ECANCELED";
  87 #endif
  88 #ifdef ECHILD
  89   case ECHILD: return "ECHILD";
  90 #endif
  91 #ifdef ECONNABORTED
  92   case ECONNABORTED: return "ECONNABORTED";
  93 #endif
  94 #ifdef ECONNREFUSED
  95   case ECONNREFUSED: return "ECONNREFUSED";
  96 #endif
  97 #ifdef ECONNRESET
  98   case ECONNRESET: return "ECONNRESET";
  99 #endif
 100 #ifdef EDEADLK
 101   case EDEADLK: return "EDEADLK";
 102 #endif
 103 #ifdef EDESTADDRREQ
 104   case EDESTADDRREQ: return "EDESTADDRREQ";
 105 #endif
 106 #ifdef EDOM
 107   case EDOM: return "EDOM";
 108 #endif
 109 #ifdef EDQUOT
 110   case EDQUOT: return "EDQUOT";
 111 #endif
 112 #ifdef EEXIST
 113   case EEXIST: return "EEXIST";
 114 #endif
 115   case EFAULT: return "EFAULT";
 116 #ifdef EFBIG
 117   case EFBIG: return "EFBIG";
 118 #endif
 119 #ifdef EHOSTUNREACH
 120   case EHOSTUNREACH: return "EHOSTUNREACH";
 121 #endif
 122 #ifdef EIDRM
 123   case EIDRM: return "EIDRM";
 124 #endif
 125 #ifdef EILSEQ
 126   case EILSEQ: return "EILSEQ";
 127 #endif
 128 #ifdef EINPROGRESS
 129   case EINPROGRESS: return "EINPROGRESS";
 130 #endif
 131   case EINTR: return "EINTR";
 132   case EINVAL: return "EINVAL";
 133 #ifdef EIO
 134   case EIO: return "EIO";
 135 #endif
 136 #ifdef EISCONN
 137   case EISCONN: return "EISCONN";
 138 #endif
 139   case EISDIR: return "EISDIR";
 140 #ifdef ELOOP
 141   case ELOOP: return "ELOOP";
 142 #endif
 143 #ifdef EMFILE
 144   case EMFILE: return "EMFILE";
 145 #endif
 146 #ifdef EMLINK
 147   case EMLINK: return "EMLINK";
 148 #endif
 149 #ifdef EMSGSIZE
 150   case EMSGSIZE: return "EMSGSIZE";
 151 #endif
 152 #ifdef EMULTIHOP
 153   case EMULTIHOP: return "EMULTIHOP";
 154 #endif
 155   case ENAMETOOLONG: return "ENAMETOOLONG";
 156 #ifdef ENETDOWN
 157   case ENETDOWN: return "ENETDOWN";
 158 #endif
 159 #ifdef ENETRESET
 160   case ENETRESET: return "ENETRESET";
 161 #endif
 162 #ifdef ENETUNREACH
 163   case ENETUNREACH: return "ENETUNREACH";
 164 #endif
 165 #ifdef ENFILE
 166   case ENFILE: return "ENFILE";
 167 #endif
 168 #ifdef ENOBUFS
 169   case ENOBUFS: return "ENOBUFS";
 170 #endif
 171 #ifdef ENODATA
 172   case ENODATA: return "ENODATA";
 173 #endif
 174 #ifdef ENODEV
 175   case ENODEV: return "ENODEV";
 176 #endif
 177   case ENOENT: return "ENOENT";
 178 #ifdef ENOEXEC
 179   case ENOEXEC: return "ENOEXEC";
 180 #endif
 181 #ifdef ENOLCK
 182   case ENOLCK: return "ENOLCK";
 183 #endif
 184 #ifdef ENOLINK
 185   case ENOLINK: return "ENOLINK";
 186 #endif
 187   case ENOMEM: return "ENOMEM";
 188 #ifdef ENOMSG
 189   case ENOMSG: return "ENOMSG";
 190 #endif
 191 #ifdef ENOPROTOOPT
 192   case ENOPROTOOPT: return "ENOPROTOOPT";
 193 #endif
 194 #ifdef ENOSPC
 195   case ENOSPC: return "ENOSPC";
 196 #endif
 197 #ifdef ENOSR
 198   case ENOSR: return "ENOSR";
 199 #endif
 200 #ifdef ENOSTR
 201   case ENOSTR: return "ENOSTR";
 202 #endif
 203 #ifdef ENOSYS
 204   case ENOSYS: return "ENOSYS";
 205 #endif
 206 #ifdef ENOTCONN
 207   case ENOTCONN: return "ENOTCONN";
 208 #endif
 209 #ifdef ENOTDIR
 210   case ENOTDIR: return "ENOTDIR";
 211 #endif
 212 // AIX: ENOTEMPTY == EEXIST
 213 #if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST)
 214   case ENOTEMPTY: return "ENOTEMPTY";
 215 #endif
 216 #ifdef ENOTSOCK
 217   case ENOTSOCK: return "ENOTSOCK";
 218 #endif
 219 #ifdef ENOTSUP
 220   case ENOTSUP: return "ENOTSUP";
 221 #endif
 222 #ifdef ENOTTY
 223   case ENOTTY: return "ENOTTY";
 224 #endif
 225 #ifdef ENXIO
 226   case ENXIO: return "ENXIO";
 227 #endif
 228 // on some unices EOPNOTSUPP==ENOTSUPP
 229 #if defined(ENOTSUP) && defined(EOPNOTSUPP) && (EOPNOTSUPP != ENOTSUP)
 230   case EOPNOTSUPP: return "EOPNOTSUPP";
 231 #endif
 232 #ifdef EOVERFLOW
 233   case EOVERFLOW: return "EOVERFLOW";
 234 #endif
 235 #ifdef EPERM
 236   case EPERM: return "EPERM";
 237 #endif
 238 #ifdef EPIPE
 239   case EPIPE: return "EPIPE";
 240 #endif
 241 #ifdef EPROTO
 242   case EPROTO: return "EPROTO";
 243 #endif
 244 #ifdef EPROTONOSUPPORT
 245   case EPROTONOSUPPORT: return "EPROTONOSUPPORT";
 246 #endif
 247 #ifdef EPROTOTYPE
 248   case EPROTOTYPE: return "EPROTOTYPE";
 249 #endif
 250   case ERANGE: return "ERANGE";
 251 #ifdef EROFS
 252   case EROFS: return "EROFS";
 253 #endif
 254 #ifdef ESPIPE
 255   case ESPIPE: return "ESPIPE";
 256 #endif
 257 #ifdef ESRCH
 258   case ESRCH: return "ESRCH";
 259 #endif
 260 #ifdef ESTALE
 261   case ESTALE: return "ESTALE";
 262 #endif
 263 #ifdef ETIME
 264   case ETIME: return "ETIME";
 265 #endif
 266 #ifdef ETIMEDOUT
 267   case ETIMEDOUT: return "ETIMEDOUT";
 268 #endif
 269 #ifdef ETXTBSY
 270   case ETXTBSY: return "ETXTBSY";
 271 #endif
 272 // on some unices EWOULDBLOCK==EAGAIN
 273 #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
 274   case EWOULDBLOCK: return "EWOULDBLOCK";
 275 #endif
 276 #ifdef EXDEV
 277   case EXDEV: return "EXDEV";
 278 #endif
 279   default: return "unknown";
 280   }
 281 }
 282 
 283 void MiscUtils::sleep_ms(int milliseconds) {
 284   // from usleep() manpage:
 285   // "The useconds argument must be less than 1,000,000  "
 286   // fallback to sleep for that.
 287   if (milliseconds >= 1000) {
 288     const int seconds = (milliseconds / 1000) + 1;
 289     ::sleep(seconds);
 290   }
 291 
 292   ::usleep(milliseconds * 1000);
 293 }
 294 
 295