[dbench @ tridge@samba.org-20070717123945-34sbk2w6rhc3wdm9]
[tridge/dbench.git] / util.c
1 /* 
2    dbench version 2
3    Copyright (C) Andrew Tridgell 1999
4    
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "dbench.h"
20
21
22 #ifndef SHM_W
23 #define SHM_W 0000200
24 #endif
25
26 #ifndef SHM_R
27 #define SHM_R 0000400
28 #endif
29
30 /* return a pointer to a anonymous shared memory segment of size "size"
31    which will persist across fork() but will disappear when all processes
32    exit 
33
34    The memory is zeroed 
35
36    This function uses system5 shared memory. It takes advantage of a property
37    that the memory is not destroyed if it is attached when the id is removed
38    */
39 void *shm_setup(int size)
40 {
41         int shmid;
42         void *ret;
43
44         shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
45         if (shmid == -1) {
46                 printf("can't get private shared memory of %d bytes: %s\n",
47                        size, 
48                        strerror(errno));
49                 exit(1);
50         }
51         ret = (void *)shmat(shmid, 0, 0);
52         if (!ret || ret == (void *)-1) {
53                 printf("can't attach to shared memory\n");
54                 return NULL;
55         }
56         /* the following releases the ipc, but note that this process
57            and all its children will still have access to the memory, its
58            just that the shmid is no longer valid for other shm calls. This
59            means we don't leave behind lots of shm segments after we exit 
60
61            See Stevens "advanced programming in unix env" for details
62            */
63         shmctl(shmid, IPC_RMID, 0);
64
65         memset(ret, 0, size);
66         
67         return ret;
68 }
69
70 /****************************************************************************
71 similar to string_sub() but allows for any character to be substituted. 
72 Use with caution!
73 ****************************************************************************/
74 void all_string_sub(char *s,const char *pattern,const char *insert)
75 {
76         char *p;
77         size_t ls,lp,li;
78
79         if (!insert || !pattern || !s) return;
80
81         ls = strlen(s);
82         lp = strlen(pattern);
83         li = strlen(insert);
84
85         if (!*pattern) return;
86         
87         while (lp <= ls && (p = strstr(s,pattern))) {
88                 memmove(p+li,p+lp,ls + 1 - (((int)(p-s)) + lp));
89                 memcpy(p, insert, li);
90                 s = p + li;
91                 ls += (li-lp);
92         }
93 }
94
95
96 /****************************************************************************
97   Get the next token from a string, return False if none found
98   handles double-quotes. 
99 Based on a routine by GJC@VILLAGE.COM. 
100 Extensively modified by Andrew.Tridgell@anu.edu.au
101 ****************************************************************************/
102 BOOL next_token(char **ptr,char *buff,char *sep)
103 {
104         static char *last_ptr=NULL;
105         char *s;
106         BOOL quoted;
107         
108         if (!ptr) ptr = &last_ptr;
109         if (!ptr) return(False);
110         
111         s = *ptr;
112         
113         /* default to simple separators */
114         if (!sep) sep = " \t\n\r";
115         
116         /* find the first non sep char */
117         while(*s && strchr(sep,*s)) s++;
118         
119         /* nothing left? */
120         if (! *s) return(False);
121         
122         /* copy over the token */
123         for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++) {
124                 if (*s == '\"') 
125                         quoted = !quoted;
126                 else
127                         *buff++ = *s;
128         }
129         
130         *ptr = (*s) ? s+1 : s;  
131         *buff = 0;
132         last_ptr = *ptr;
133         
134         return(True);
135 }
136
137 /*
138   return a timeval for the current time
139 */
140 struct timeval timeval_current(void)
141 {
142         struct timeval tv;
143         gettimeofday(&tv, NULL);
144         return tv;
145 }
146
147 /*
148   return the number of seconds elapsed since a given time
149 */
150 double timeval_elapsed(struct timeval *tv)
151 {
152         struct timeval tv2 = timeval_current();
153         return (tv2.tv_sec - tv->tv_sec) + 
154                (tv2.tv_usec - tv->tv_usec)*1.0e-6;
155 }
156
157 /*
158   return the number of seconds elapsed since a given time
159 */
160 double timeval_elapsed2(struct timeval *tv1, struct timeval *tv2)
161 {
162         return (tv2->tv_sec - tv1->tv_sec) + 
163                (tv2->tv_usec - tv1->tv_usec)*1.0e-6;
164 }
165
166
167
168 /**
169  Sleep for a specified number of milliseconds.
170 **/
171 void msleep(unsigned int t)
172 {
173         struct timeval tval;  
174
175         tval.tv_sec = t/1000;
176         tval.tv_usec = 1000*(t%1000);
177         /* this should be the real select - do NOT replace
178            with sys_select() */
179         select(0,NULL,NULL,NULL,&tval);
180 }