xref: /titanic_52/usr/src/cmd/sendmail/db/os/os_spin.c (revision fd845fc0cb4fbc8e85f974e2e4eaacca1cc26e81)
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1997, 1998
5  *	Sleepycat Software.  All rights reserved.
6  */
7 
8 #include "config.h"
9 
10 #ifndef lint
11 static const char sccsid[] = "@(#)os_spin.c	10.10 (Sleepycat) 10/12/98";
12 #endif /* not lint */
13 
14 #ifndef NO_SYSTEM_INCLUDES
15 #include <sys/types.h>
16 #if defined(HAVE_PSTAT_GETDYNAMIC)
17 #include <sys/pstat.h>
18 #endif
19 
20 #include <limits.h>
21 #include <unistd.h>
22 #endif
23 
24 #include "db_int.h"
25 #include "os_jump.h"
26 
27 #if defined(HAVE_PSTAT_GETDYNAMIC)
28 /*
29  * __os_pstat_getdynamic --
30  *	HP/UX.
31  */
32 static int
33 __os_pstat_getdynamic()
34 {
35 	struct pst_dynamic psd;
36 
37 	return (pstat_getdynamic(&psd,
38 	    sizeof(psd), (size_t)1, 0) == -1 ? 1 : psd.psd_proc_cnt);
39 }
40 #endif
41 
42 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
43 /*
44  * __os_sysconf --
45  *	Solaris, Linux.
46  */
47 static int
48 __os_sysconf()
49 {
50 	int nproc;
51 
52 	return ((nproc = sysconf(_SC_NPROCESSORS_ONLN)) > 1 ? nproc : 1);
53 }
54 #endif
55 
56 /*
57  * __os_spin --
58  *	Return the number of default spins before blocking.
59  *
60  * PUBLIC: int __os_spin __P((void));
61  */
62 int
63 __os_spin()
64 {
65 	/*
66 	 * If the application specified a value or we've already figured it
67 	 * out, return it.
68 	 *
69 	 * XXX
70 	 * We don't want to repeatedly call the underlying function because
71 	 * it can be expensive (e.g., requiring multiple filesystem accesses
72 	 * under Debian Linux).
73 	 */
74 	if (DB_GLOBAL(db_tsl_spins) != 0)
75 		return (DB_GLOBAL(db_tsl_spins));
76 
77 	DB_GLOBAL(db_tsl_spins) = 1;
78 #if defined(HAVE_PSTAT_GETDYNAMIC)
79 	DB_GLOBAL(db_tsl_spins) = __os_pstat_getdynamic();
80 #endif
81 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
82 	DB_GLOBAL(db_tsl_spins) = __os_sysconf();
83 #endif
84 
85 	/*
86 	 * Spin 50 times per processor, we have anecdotal evidence that this
87 	 * is a reasonable value.
88 	 */
89 	DB_GLOBAL(db_tsl_spins) *= 50;
90 
91 	return (DB_GLOBAL(db_tsl_spins));
92 }
93 
94 /*
95  * __os_yield --
96  *	Yield the processor.
97  *
98  * PUBLIC: void __os_yield __P((u_long));
99  */
100 void
101 __os_yield(usecs)
102 	u_long usecs;
103 {
104 	if (__db_jump.j_yield != NULL && __db_jump.j_yield() == 0)
105 		return;
106 	__os_sleep(0, usecs);
107 }
108