1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the License). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/CDDL.txt 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/CDDL.txt. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets [] replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * The following notices accompanied the original version of this file: 32 * 33 * Copyright (c) 1982, 1986 Regents of the University of California. 34 * All rights reserved. The Berkeley software License Agreement 35 * specifies the terms and conditions for redistribution. 36 */ 37 38 #ifndef _OS_H 39 #define _OS_H 40 41 #pragma ident "@(#)os.h 1.125 08/07/17 SMI" 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 #ifdef __cplusplus 48 } 49 #endif 50 51 #include <sys/os_compat.h> 52 53 #if defined(__cplusplus) 54 55 /* 56 * os.h - specification of the OS services that Solaris MC components 57 * can call from C++ in a portable way both in userland and in 58 * the kernel. 59 */ 60 61 #include <sys/types.h> 62 #if __cplusplus < 199711 63 /* For emulation "bool" type till compiler supports built-in bool type */ 64 #include <sys/boolean.h> 65 #endif 66 67 #ifndef linux 68 #define BUG_4630016 69 #endif 70 71 #ifdef BUG_4630016 72 #ifndef _KERNEL 73 #define _KERNEL 74 #include <sys/atomic.h> 75 #undef _KERNEL 76 #else // _KERNEL 77 #include <sys/atomic.h> 78 #endif // _KERNEL 79 #endif 80 81 #ifndef linux 82 #include <sys/systm.h> 83 #endif 84 #include <sys/time.h> 85 #include <orb/infrastructure/fork.h> 86 87 #if defined(DEBUG) 88 #define INTR_DEBUG 89 #endif 90 91 extern "C" { 92 void symtracedump(void); 93 } 94 95 #include <netdb.h> 96 #include <netinet/in.h> 97 #include <sys/cl_assert.h> 98 99 #ifdef linux 100 #include <pthread.h> 101 #include <semaphore.h> 102 #endif 103 104 #ifdef _KERNEL 105 #ifndef linux 106 #include <sys/thread.h> 107 #include <sys/mutex.h> 108 #include <sys/rwlock.h> 109 #include <sys/ksynch.h> 110 #include <sys/proc.h> 111 #include <sys/stack.h> 112 #include <sys/strsubr.h> 113 #include <sys/kmem.h> 114 #include <sys/debug.h> 115 #include <sys/bitmap.h> 116 #include <sys/kobj.h> 117 #include <sys/dirent.h> 118 #endif /* linux */ 119 120 #else // _KERNEL 121 122 #include <stdio.h> // for BUFSIZ 123 #include <stdlib.h> // for atoi 124 #ifdef linux 125 #include <pthread.h> 126 #include <semaphore.h> 127 #else 128 #include <thread.h> 129 #include <synch.h> 130 #endif 131 #include <string.h> 132 #include <errno.h> 133 #include <strings.h> 134 #include <ctype.h> 135 #include <unistd.h> 136 #include <dirent.h> 137 #include <pwd.h> 138 139 #define ATOMIC_HASH_SIZE 256 140 #define ATOMIC_HASH_SHIFT 6 141 #define ATOMIC_HASH(addr) \ 142 (((uintptr_t)(addr) >> ATOMIC_HASH_SHIFT) & ATOMIC_HASH_MASK) 143 #define ATOMIC_HASH_MASK (ATOMIC_HASH_SIZE - 1) 144 145 #define ATOMIC_LOCK(addr) &atomic_lock[ATOMIC_HASH(addr)] 146 147 #endif // _KERNEL 148 149 #include <sys/sc_syslog_msg.h> // for sc_syslog_msg class 150 151 #ifdef u 152 #undef u 153 #endif 154 155 #ifdef paddr 156 #undef paddr 157 #endif 158 159 #ifndef NULL 160 #define NULL 0 161 #endif 162 163 // 164 // OS dependent functions needed for C/C++ programs 165 // 166 extern "C" int mkdirp(const char *path, mode_t mode); 167 extern "C" hrtime_t gethrtime(); 168 #ifdef linux 169 extern "C" int getnetbyname_r(const char*, struct netent*, char*, size_t, 170 struct netent**, int*); 171 extern "C" int getrpcbyname_r(const char*, struct rpcent*, char*, size_t, 172 struct rpcent**) throw(); 173 #else 174 extern "C" struct netent *getnetbyname_r(const char *, struct netent*, 175 char*, int); 176 extern "C" struct rpcent *getrpcbyname_r(const char *, struct rpcent*, 177 char*, int); 178 #endif 179 extern "C" struct hostent *getipnodebyname(const char *name, int af, 180 int flags, int *error_num); 181 extern "C" void freehostent(struct hostent *hp); 182 183 184 // 185 // maxusers - unode version defines the maximum number of users 186 // a unode system supports. This really is used for system 187 // configuration. 188 // 189 extern int maxusers; 190 #ifndef linux 191 #include <sys/clconf.h> 192 #ifndef _KERNEL 193 extern void clconf_init(void); 194 extern nodeid_t clconf_get_nodeid(void); 195 #endif 196 #else 197 extern void clconf_init(); 198 #endif 199 200 // 201 // The namespace os:: includes those OS services that Solaris MC components 202 // can call from C++ in a portable way. Both userland and kernel level 203 // implementations of this API are provided. 204 // 205 // The C equivalent of this API is defined in <os_c.h> 206 // 207 208 class os { 209 public: 210 #ifdef _KERNEL 211 enum mem_alloc_type { SLEEP = KM_SLEEP, NO_SLEEP = KM_NOSLEEP }; 212 #else 213 enum mem_alloc_type { SLEEP, NO_SLEEP }; 214 #endif 215 enum mem_zero_type { DONTZERO, ZERO }; 216 217 #ifdef _KERNEL 218 typedef kthread_t *threadid_t; 219 #else 220 typedef thread_t threadid_t; 221 #endif 222 static os::threadid_t threadid(); 223 224 class condvar_t; // forward declaration 225 226 // 227 // class mutex - synchronization mutex 228 // 229 class mutex_t { 230 friend class condvar_t; 231 #ifndef _KERNEL 232 // 233 // following friend class defines pthread_atfork handler 234 // functions. This is defined friend of mutex class so that 235 // the owner of the lock can be updated to new threadid 236 // in the child process. 237 // 238 friend class pthread_atfork_handler; 239 #endif // _KERNEL 240 public: 241 mutex_t(); 242 ~mutex_t(); 243 void lock(); 244 int try_lock(); 245 void unlock(); 246 int lock_held(); 247 int lock_not_held(); 248 uint64_t owner(); 249 250 private: 251 // 252 // when a process fork's a child, it may inherit a lock 253 // in a locked state, and the owner of the lock is set to 254 // threadid of the locking thread of the parent. 255 // The owner of lock should be set to threadid of the locking 256 // thread in the child process. This interface is called by 257 // the child handler defined in fork.cc so as to set the 258 // owner of the lock to threadid in the child process. 259 // 260 // Note: this interface should be called only by 261 // pthread_handler's defined in fork.cc. 262 // 263 void set_owner(); 264 #ifdef _KERNEL 265 ::kmutex_t _mutex; 266 #else // _KERNEL 267 #ifdef linux 268 ::pthread_mutex_t _mutex; 269 #else 270 ::mutex_t _mutex; 271 #endif 272 os::threadid_t _owner; // For lock held and assertions 273 #endif // _KERNEL 274 275 // Disallow assignments and pass by value 276 mutex_t(const mutex_t &); 277 mutex_t &operator = (mutex_t &); 278 }; 279 280 // 281 // class rwlock_t - reader/writer lock 282 // 283 class rwlock_t { 284 public: 285 rwlock_t(); 286 ~rwlock_t(); 287 void rdlock(); 288 void wrlock(); 289 int try_rdlock(); 290 int try_wrlock(); 291 void unlock(); 292 int lock_held(); 293 int read_held(); 294 int write_held(); 295 #ifdef _KERNEL 296 // 297 // The methods try_upgrade(), downgrade(), and rw_owner() 298 // are not supported in userland. There is no 299 // corresponding Solaris system call to wrap around. 300 // 301 302 int try_upgrade(); 303 void downgrade(); 304 threadid_t rw_owner(); 305 #endif 306 private: 307 #ifdef _KERNEL 308 ::krwlock_t _rwlock; 309 #else // _KERNEL 310 #ifdef linux 311 ::pthread_rwlock_t _rwlock; 312 #else 313 ::rwlock_t _rwlock; 314 #endif 315 #endif // _KERNEL 316 317 // Disallow assignments and pass by value 318 rwlock_t(const rwlock_t &); 319 rwlock_t &operator = (rwlock_t &); 320 }; 321 322 class systime; 323 324 // 325 // functions for atomic operations { see <sys/atomic.h> } 326 // add delta atomically to tgt 327 // 328 static void atomic_add_16(uint16_t *tgt, int16_t delta); 329 static void atomic_add_32(uint32_t *tgt, int32_t delta); 330 static void atomic_add_64(uint64_t *tgt, int64_t delta); 331 // 332 // as above, but also return final value of target 333 // 334 static uint16_t atomic_add_16_nv(uint16_t *tgt, int16_t delta); 335 static uint32_t atomic_add_32_nv(uint32_t *tgt, int32_t delta); 336 static uint64_t atomic_add_64_nv(uint64_t *tgt, int64_t delta); 337 338 #ifdef _KERNEL 339 // 340 // compare and swap if tgt == cmp then set tgt to nv 341 // and return old value of tgt 342 // 343 // If there are requirements for user-land versions of the 344 // cas* functions, atomic_cas_32(3C), atomic_cas_64(3C) and 345 // atomic_cas_ptr(3C) can be used. 346 // 347 static uint32_t cas32(uint32_t *tgt, uint32_t cmp, uint32_t nv); 348 static uint64_t cas64(uint64_t *tgt, uint64_t cmp, uint64_t nv); 349 // 350 // as above, but with pointers 351 // 352 static void *casptr(void **tgt, void *cmp, void *nval); 353 // 354 // end of atomic operations from <sys/atomic.h> 355 // 356 #endif // _KERNEL 357 358 // 359 // Atomic copies (for guaranteed atomic copies across architectures) 360 // This function makes no guarantees as to atomic reads. If you want 361 // to read atomically, use this function to make a local copy and read 362 // that. Both arguments must point to addresses that are 8 byte 363 // aligned. 364 // 365 static void atomic_copy_64(uint64_t *tgt, uint64_t *src); 366 367 // 368 // variations of allocb/dupb that support os::SLEEP allocations 369 // XX Currently implemented in _KERNEL only, 370 // would be nice to have user land emulation too 371 // 372 static mblk_t *allocb(uint_t size, uint_t pri, os::mem_alloc_type flag); 373 static mblk_t *dupb(mblk_t *mp, uint_t pri, os::mem_alloc_type flag); 374 375 // 376 // class condvar - condition variable 377 // 378 // The condvar can only be used with one lock. 379 // The first lock used with the condvar becomes the only lock 380 // which the condvar will accept subsequently. 381 // 382 class condvar_t { 383 public: 384 condvar_t(); 385 ~condvar_t(); 386 387 // 388 // These result values correspond to those returned by the 389 // kernel so that kernel developers may use the actual values 390 // if they prefer. 391 // 392 enum wait_result { SIGNALED = 0, TIMEDOUT = -1, NORMAL = 1 }; 393 394 // There are 4 variants on wait. The userland version of the 395 // wait() and timedwait() can be woken by signals or fork. If 396 // they are NORMAL is returned. 397 // 398 // For user, if there is no signal handler defined for the 399 // signal in question, the program will segv. 400 void wait(mutex_t *lockp); 401 // returns NORMAL or SIGNALED. 402 wait_result wait_sig(mutex_t *lockp); 403 // returns NORMAL or TIMEDOUT 404 wait_result timedwait(mutex_t *lockp, systime *timeout); 405 // returns NORMAL or SIGNALED or TIMEDOUT 406 wait_result timedwait_sig(mutex_t *lockp, systime *timeout); 407 408 void signal(); 409 void broadcast(); 410 411 #ifdef DEBUG 412 // 413 // The condvar_t will no longer use the lock currently 414 // associated with it and the condvar_t is idle. 415 // Reset the condvar_t to its initial state. 416 // 417 void reset(); 418 #endif 419 420 private: 421 422 #ifdef linux 423 ::pthread_cond_t _cv; 424 #else /* linux */ 425 #ifdef _KERNEL 426 ::kcondvar_t _cv; 427 #else // _KERNEL 428 ::cond_t _cv; 429 #endif 430 #endif // _KERNEL 431 432 // Called before wait. 433 void debug_pre(os::mutex_t *lockp); 434 // Called after wait. 435 void debug_post(); 436 #ifdef DEBUG 437 int num_waiting; 438 os::mutex_t *wait_lock; // Only this lock can be used, 439 // once set 440 #endif 441 442 // Disallow assignments and pass by value 443 condvar_t(const condvar_t &); 444 condvar_t &operator = (condvar_t &); 445 }; 446 447 // class sem_t 448 class sem_t { 449 public: 450 sem_t(uint_t initval); 451 sem_t(); 452 ~sem_t(); 453 454 void p(); 455 int tryp(); 456 void v(); 457 458 private: 459 #ifdef _KERNEL 460 ::ksema_t _sem; 461 #else // _KERNEL 462 #ifdef linux 463 ::sem_t _sem; 464 #else 465 ::sema_t _sem; 466 #endif 467 #endif // _KERNEL 468 469 // Disallow assignments and pass by value 470 sem_t(const sem_t &); 471 sem_t &operator = (sem_t &); 472 }; 473 474 // 475 // class notify_t 476 // 477 // Used to encapsulate a cv + flag (global mutex) 478 // 479 class notify_t { 480 public : 481 enum wait_state { WAITING, DONE }; 482 483 // constructor initialized to WAITING 484 notify_t(); 485 486 // Set flag to DONE and signal all waiters 487 // This does a cv.broadcast to wake up all waiters 488 // There is no equivalent of cv.signal as the class needs to 489 // be reinitialized before new waiter can wait on it. 490 void signal(); 491 492 // Wait for flag to change state. 493 void wait(); 494 495 // Timed Wait for flag to change state. Returns current state 496 wait_state timedwait(os::systime &); 497 498 // reinitialize, if old flag is WAITING, wait for old signal 499 // Returns 0 on failure (nonblocking only), 1 on success 500 int reinit(os::mem_alloc_type); 501 502 // Return current state. Mostly for debug purposes 503 wait_state get_state(); 504 private : 505 wait_state flag; 506 os::condvar_t cv; 507 static os::mutex_t notify_lock; 508 509 // Disallow assignments and pass by value 510 notify_t(const notify_t &); 511 notify_t &operator = (notify_t &); 512 }; 513 514 // 515 // class thread 516 // 517 518 // XXX - need to declare an API to allow creation of a new thread. 519 class thread { 520 public: 521 #ifdef _KERNEL 522 static os::threadid_t create(void *(*func)(void *)); 523 #else 524 static int create(void *, size_t, void *(*)(void *), 525 void *, long, threadid_t *); 526 #endif 527 static void exit(void *); 528 static int main(void); 529 static int join(threadid_t, threadid_t *departed = NULL, 530 void **status = NULL); 531 static threadid_t self(void) { return (os::threadid()); } 532 static void sigsetmask(int, sigset_t *, sigset_t *); 533 static int getconcurrency(); 534 static int setconcurrency(int); 535 }; 536 537 static int drv_getparm(unsigned int, void *); 538 static int drv_priv(cred_t *cr); 539 static int sysinfo(int command, char *buf, long count); 540 static struct passwd *getpwnam(const char *name, struct passwd 541 *pwd, char *buffer, int buflen); 542 static struct passwd *getpwuid(uid_t uid, struct passwd *pwd, 543 char *buffer, int buflen); 544 545 // 546 // Thread specific data 547 // 548 class tsd { 549 public: 550 typedef void (*freef_t)(void *value); 551 tsd(freef_t = NULL); 552 ~tsd(); 553 void set_tsd(uintptr_t); // set value 554 uintptr_t get_tsd() const; // get value 555 private: 556 uint_t _key; 557 558 // Disallow assignments and pass by value 559 tsd(const tsd &); 560 tsd &operator = (tsd &); 561 }; 562 563 // 564 // debugging code to check for nonblocking contexts 565 // 566 #ifndef linux 567 static 568 #endif 569 class envchk { 570 public: 571 // 572 // nbtype - defines different kinds of nonblocking context. 573 // The system uses these enum values to identify when 574 // certain operations cannot be performed. 575 // 576 enum nbtype {NB_INTR = 0x1, // Interrupt 577 NB_INVO = 0x2, // Invocation 578 NB_RECONF = 0x4}; // Node reconfiguration 579 580 static void set_nonblocking(nbtype); 581 static void clear_nonblocking(nbtype); 582 static bool is_nonblocking(int); 583 static void check_nonblocking(int, char *); 584 private: 585 #ifdef INTR_DEBUG 586 static tsd env; 587 #endif 588 // Disallow assignments and pass by value 589 envchk(const envchk &); 590 envchk &operator = (envchk &); 591 }; 592 typedef ::hrtime_t hrtime_t; 593 static os::hrtime_t gethrtime(); 594 595 static void tracedump(); 596 597 typedef clock_t usec_t; 598 599 static void usecsleep(os::usec_t sleeptime); 600 601 // 602 // Methods for time of day computations. Parts of it have been 603 // adapted from userland ctime implementation and other parts 604 // have been copied from other parts of the kernel to eliminate 605 // dependencies. 606 // 607 class tod { 608 public: 609 // Maximum length of a date string including the terminating 610 // NULL character returned by ctime_r. 611 enum {CTIME_STR_LEN = 32}; 612 613 // Converts seconds since epoch to a printable date string. 614 // Adapted from userland ctime_r. 615 static char *ctime_r(const time_t *, char *, int); 616 private: 617 #ifdef _KERNEL 618 // Represents time of day. Taken from common/sys/time.h. 619 typedef struct todinfo { 620 int tod_sec; // seconds 0-59 621 int tod_min; // minutes 0-59 622 int tod_hour; // hours 0-23 623 int tod_dow; // day of week 1-7 624 int tod_day; // day of month 1-31 625 int tod_month; // month 1-12 626 int tod_year; // year 70+ 627 } todinfo_t; 628 629 // Splits seconds since epoch into year, month, day, 630 // hours, minutes, seconds. 631 // Copied from usr/src/uts/common/os/timers.c 632 static todinfo_t utc_to_tod(time_t); 633 634 // The following methods are supporting methods for ctime_r 635 // and have been adapted from their userland counterparts. 636 static char *ct_numb(char *, int); 637 static char *asctime_r(const todinfo_t *, char *, int); 638 #endif 639 }; 640 641 // 642 // miscellaneous library functions 643 // 644 static int strcmp(const char *s1, const char *s2); 645 static int strncmp(const char *s1, const char *s2, size_t n); 646 static int strncasecmp(const char *s1, const char *s2, size_t n); 647 static char *strcpy(char *dst, const char *src); 648 static char *strncpy(char *dst, const char *src, size_t n); 649 static char *strstr(const char *s1, const char *s2); 650 651 static size_t strspn(const char *string, const char *charset); 652 static char *strpbrk(const char *string, const char *brkset); 653 static char *strtok_r(char *string, const char *sepset, char **lasts); 654 655 // strdup differs from the normal strdup in two ways: 656 // os::strdup allocates memory using "new" and not malloc 657 // The returns char * should be freed with delete [] ... 658 // os::strdup returns NULL if either string is NULL or 659 // the allocation failed (the kernel version does not return NULL) 660 static char *strdup(const char *string); 661 662 static size_t strlen(const char *str); 663 static void sprintf(char *buf, const char *fmt, ...); 664 static int snprintf(char *buf, size_t n, const char *fmt, ...); 665 666 static void *bsearch(const void *key, const void *base, 667 size_t nel, size_t size, 668 int (*compar)(const void *, const void *)); 669 670 static void warning(const char *fmt, ...); 671 static void printf(const char *fmt, ...); 672 static void prom_printf(const char *fmt, ...); // make sure it gets out 673 static void abort(); 674 static void panic(const char *, ...); 675 static void log_syslog(const char *fmt, ...); 676 static void symtracedump(void); 677 678 static int cladm(int facility, int command, void *arg); 679 680 static int create_dir(char *); 681 static int rm_dir(char *); 682 static int file_link(char *, char *); 683 static int file_rename(char *, char *); 684 static int file_unlink(char *); 685 static int file_copy(char *, char *); 686 687 // Read-only file stream object 688 class rfile { 689 public: 690 rfile(); 691 ~rfile(); 692 bool open(char *); 693 bool isopen(); 694 size_t read(char *, size_t, size_t); 695 int fgetc(); 696 int ungetc(int); 697 void close(); 698 private: 699 #ifdef _KERNEL 700 struct _buf *f; 701 #else 702 FILE *f; 703 #endif 704 }; 705 706 static int mkdirp(const char *path, mode_t mode); 707 static int find_unique_subdir(char *path, char *foundpath); 708 709 #ifdef _KERNEL 710 typedef ::dirent64_t dirent_t; 711 #else 712 #ifdef linux 713 typedef struct dirent dirent_t; 714 #else 715 typedef ::dirent_t dirent_t; 716 #endif 717 #endif 718 719 // os interface for opendir/readdir 720 class rdir { 721 public: 722 rdir(); 723 ~rdir(); 724 bool open(char *); 725 bool isopen(); 726 dirent_t *read(); 727 void close(); 728 private: 729 #ifdef _KERNEL 730 enum { maxlen = 1024 }; // buffer size 731 732 vnode_t *dvp; // directory vnode 733 char *rawdirp; // buffer for directory contents 734 struct dirent64 *nextp; // pointer to next unread entry 735 struct dirent64 *lastp; // pointer to last entry in rawdirp 736 offset_t doff; // directory offset to read from 737 #else 738 DIR *d; 739 #endif 740 }; 741 742 // translate a string decimal internet address to a inaddr_t 743 // NOTE: This function behaves differently than 744 // the user-level library function inet_addr 745 static in_addr_t inet_addr(const char *); 746 747 // sc_syslog_msg interfaces 748 749 // 750 // The method calls in turn invoke openlog(3) and syslog(3) in 751 // user-land and cmn_err(9F) in kernel-land. 752 // The second parameter to openlog(3) viz. logopt cannot be specified 753 // when invoking methods of sc_syslog_msg class. It is always set 754 // to LOG_CONS by methods in sc_syslog_msg class. 755 // 756 // Other parameters to openlog(3) such as ident (1st parameter) 757 // can be specified in the constructor 758 // of sc_syslog_msg class for user-land modules. 759 // facility is always set to LOG_DAEMON for user-land modules. 760 // 761 762 class sc_syslog_msg { 763 public: 764 // 765 // Constructor 766 // 767 // Paramters: 768 // 769 // resource_type_specific_tag - 770 // This tag will become part of the message id. of the 771 // logged message. 772 // - It should not be NULL. 773 // - Some resource_type_specific_tags 774 // are defined in sc_syslog_msg.h 775 // 776 // resource_name - 777 // resource_type_specific_tag and resource_name are 778 // concatenated to create the <message tag> part of the 779 // message id. 780 // - It should not be NULL. 781 // - It should be unique clusterwide. 782 // For example, if it is a message logged by CMM for 783 // node 2, resource_name should be "2". 784 // 785 // 786 787 sc_syslog_msg( 788 const char *resource_type_specific_tag, 789 const char *resource_name, 790 void *); 791 792 // 793 // log() - Logs a message with the syslog facility 794 // 795 // Paramters: 796 // 797 // priority - priority of the logged message. see syslog(3) 798 // or cmn_err(9F) for additional information. 799 // Some common priority values are defined in 800 // sc_syslog_msg.h to avoid having to put ifdefs 801 // in the code that is shared in kernel and 802 // user-land. 803 // 804 // format - Formatted message as it is logged using syslog(3) 805 // or cmn_err(9F) 806 // 807 // 808 sc_syslog_msg_status_t log( 809 int priority, 810 sc_event_type_t event_type, 811 const char *format, 812 ...); 813 814 ~sc_syslog_msg(); 815 private: 816 sc_syslog_msg_handle_t msg_handle; 817 818 // Disallow assignments and pass by value 819 sc_syslog_msg(const sc_syslog_msg &); 820 sc_syslog_msg &operator = (sc_syslog_msg &); 821 }; // end of sc_syslog_msg 822 823 // 824 // class systime 825 // 826 // Simple class for dealing with system time. 827 class systime { 828 friend class condvar_t; 829 public: 830 // constructor 831 systime(usec_t offset = 0); 832 833 // Set the time of this object to some offset relative to now. 834 void setreltime(usec_t offset); 835 836 // Is this time in the past. 837 bool is_past(); 838 839 // Is this time in the future. 840 bool is_future(); 841 842 // Is this time before that. 843 bool is_before(systime &); 844 845 // Set the time. 846 void set(systime &); 847 848 private: 849 #ifdef _KERNEL 850 long _time; 851 #else // _KERNEL 852 timestruc_t _time; 853 #endif // _KERNEL 854 855 // Disallow assignments and pass by value 856 systime(const systime &); 857 systime &operator = (systime &); 858 }; 859 860 // 861 // class ctype 862 // 863 // simple routines for deriving character types 864 // 865 // NB: For the kernel these are optimized since they 866 // need not perform internationalization. 867 // The userland versions map directly to libc. 868 // 869 // This list isn't complete, but contains the methods 870 // we currently use in the kernel. 871 // 872 // Since the is* functions are macros, we cannot simply 873 // map the names one for one (they're all expanded inline). 874 // Given that limitation, we've added an underscore. 875 // 876 class ctype { 877 public: 878 static int is_digit(int c); 879 static int is_alpha(int c); 880 static int is_xdigit(int c); 881 static int is_upper(int c); 882 static int is_lower(int c); 883 static int is_space(int c); 884 }; 885 886 static int atoi(const char *str); 887 888 // Convert int to char *. Caller needs to make sure 889 // the space pointed by char * is big enough. It returns the 890 // number of digits copied. 891 static int itoa(int, char *, uint_t base = 10); 892 893 // 894 // Find highest and lowest one bit set. 895 // Returns bit number + 1 of bit that is set, otherwise returns 0. 896 // Low order bit is 0, high order bit is 31. 897 // 898 static int highbit(ulong_t); 899 static int lowbit(ulong_t); 900 901 // 902 // copyin - replace with a bcopy function call and a sequence 903 // operator (the comma) followed by the return value of success. 904 // The unode copyin has no problems crossing from user to kernel space. 905 // 906 // copyout - replace with a bcopy function call and a sequence 907 // operator (the comma) followed by the return value of success. 908 // The unode copyout has no problems crossing from kernel to user space. 909 // 910 #ifndef _KERNEL 911 static int copyin(const void *src, void *dest, size_t size) 912 { bcopy(src, dest, size); return (0); } 913 static int x_copyin(const void *src, void *dest, size_t size) 914 { bcopy(src, dest, size); return (0); } 915 static int copyout(const void *src, void *dest, size_t size) 916 { bcopy(src, dest, size); return (0); } 917 static int x_copyout(const void *src, void *dest, size_t size) 918 { bcopy(src, dest, size); return (0); } 919 static int copyoutstr(const void *src, void *dest, size_t, 920 size_t *lencopied) 921 { *(lencopied) = strlen((const char *)src); 922 bcopy(src, dest, *(lencopied)); return (0); } 923 #else 924 static int copyin(const void *src, void *dest, size_t size) 925 { return (::copyin(src, dest, size)); } 926 static int x_copyin(const void *src, void *dest, size_t size) 927 { return (::xcopyin(src, dest, size)); } 928 static int copyout(const void *src, void *dest, size_t size) 929 { return (::copyout(src, dest, size)); } 930 static int x_copyout(const void *src, void *dest, size_t size) 931 { return (::xcopyout(src, dest, size)); } 932 static int copyoutstr(const void *src, void *dest, size_t size, 933 size_t *lencopied) { 934 return (::copyoutstr((const char *)src, (char *)dest, size, 935 lencopied)); 936 } 937 #endif 938 // 939 // str2sig() only exists on Solaris. On Linux, we need to 940 // provide our own implementation. 941 // 942 static int str2sig(const char *s, int *sigp); 943 944 // Abstraction of getnetbyname_r() 945 static struct netent *getnetbyname_r(const char *name, 946 struct netent *result_buf, char *buffer, int *res); 947 // Abstraction of getrpcbyname_r() 948 static struct rpcent *getrpcbyname_r(const char *name, 949 struct rpcent *result_buf, char *buffer, int buflen); 950 951 private: 952 953 #ifdef _KERNEL_ORB 954 // Used by usecsleep() 955 static mutex_t sleep_mutex; 956 static condvar_t sleep_cv; 957 #endif 958 959 }; // class os 960 961 void *shared_new(size_t, os::mem_alloc_type, os::mem_zero_type); 962 963 // 964 // In a 32-bit kernel, size_t is defined as an unsigned long. But the 965 // C++ compiler "knows" that size_t is an unsigned int, so if we define 966 // new operators using size_t we'll get compilation errors. So we use 967 // galsize_t when defining new and delete operators. Everywhere else 968 // we use size_t. 969 // 970 #if defined(_LP64) || !defined(_I32LPx) 971 typedef size_t galsize_t; 972 #else 973 typedef uint_t galsize_t; 974 #endif 975 976 #ifdef _KERNEL 977 978 // If inlines are disabled (and won't be seen by including os_in.h) 979 // we need prototypes for the forms of operator new(). 980 981 #ifdef NOINLINES 982 void *operator new(galsize_t, os::mem_zero_type); 983 void *operator new(galsize_t, os::mem_alloc_type); 984 void *operator new(galsize_t, os::mem_alloc_type, os::mem_zero_type); 985 #endif 986 987 // id for "not a thread" 988 // Disabling this as this results in 1 variable instance per .cc file! 989 // const os::threadid_t NO_THREAD = NULL; 990 991 #else // _KERNEL 992 993 #ifdef NOINLINES 994 void *operator new(size_t, os::mem_zero_type); 995 void *operator new(size_t, os::mem_alloc_type); 996 void *operator new(size_t, os::mem_alloc_type, os::mem_zero_type); 997 998 #endif 999 1000 // id for "not a thread" 1001 const os::threadid_t NO_THREAD = 0; 1002 1003 extern os::mutex_t atomic_lock[ATOMIC_HASH_SIZE]; 1004 1005 #endif // _KERNEL 1006 1007 #include <sys/knewdel.h> 1008 1009 // If inlines are enabled the _in.h headers are included here, 1010 // otherwise non-inline methods are built into libkos/libuos 1011 // (see os_misc.cc). 1012 1013 #ifndef NOINLINES 1014 #include <sys/os_in.h> 1015 1016 #ifdef DEBUGGER_PRINT 1017 #include <dbg_os_in.h> 1018 inline void * 1019 /*CSTYLED*/ 1020 operator new[](galsize_t len, os::mem_alloc_type flag) 1021 { 1022 extern void *shared_new(size_t, os::mem_alloc_type, os::mem_zero_type); 1023 1024 return (shared_new((size_t)len, flag, os::DONTZERO)); 1025 } 1026 #else 1027 #ifdef _KERNEL 1028 #include <sys/kos_in.h> 1029 #else // _KERNEL 1030 #include <sys/uos_in.h> 1031 #endif // _KERNEL 1032 #endif // DEBUGGER_PRINT 1033 1034 #endif // _NOINLINES 1035 1036 #else /* __cplusplus */ 1037 1038 /* 1039 * OS dependent functions needed for C programs 1040 */ 1041 #ifdef linux 1042 extern int mkdirp(const char *path, mode_t mode); 1043 extern hrtime_t gethrtime(); 1044 extern struct hostent *getipnodebyname(const char *name, int af, 1045 int flags, int *error_num); 1046 extern void freehostent(struct hostent *hp); 1047 #endif 1048 1049 #endif /* __cplusplus */ 1050 1051 #ifdef __cplusplus 1052 extern "C" { 1053 #endif 1054 1055 #ifdef __cplusplus 1056 } 1057 #endif 1058 1059 #endif /* _OS_H */ 1060