1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 
10 #if defined(__cplusplus) || defined(c_plusplus)
11 extern "C" {
12 #endif
13 
14 #ifndef _DXI_ADVANCED_H_
15 #define _DXI_ADVANCED_H_
16 
17 /* TeX starts here. Do not remove this comment. */
18 
19 /*
20 \chapter{Advanced Routines}
21 This appendix describes advanced routines that are not of interest
22 to most module writers.  This includes locking routines, which are
23 not recommended for general use in modules because of the difficulty
24 of avoiding deadlocks, and system routines that are only of interest
25 to the executive or standalone programs.
26 */
27 
28 /*
29 \section{Locking}
30 Normally, the routines described in this section are not used by a
31 module, but rather are used only in the implementation of data model routines.
32 The reason for this is that great care in the use of locks is required to
33 avoid deadlock in a parallel system.  They are documented here primarily for
34 internal use within the data model access routines and in the executive.
35 Thus, they are intentionally given names in a style different from the
36 rest of the library.
37 */
38 #if defined(DXD_USE_MUTEX_LOCKS) && DXD_USE_MUTEX_LOCKS==1
39 #include <synch.h>
40 typedef volatile mutex_t lock_type;
41 #elif defined(alphax)
42 #include <sys/mman.h>
43 typedef msemaphore lock_type;
44 #else
45 typedef volatile int lock_type;
46 #endif
47 
48 void DXenable_locks(int enable);
49 /**
50 \index{enable\_locks}
51 Enables or disables locks.  On some systems, issuing and releasing locks
52 takes a significant amount of time.  This overhead is unnecessary when
53 multiple execution threads do not exist or are not sharing state.  By
54 default, DX internal locking is enabled. Calling this routine with an
55 {\tt enable} value of 0 causes mutex locking mechanisms to be bypassed and
56 all DXlock, DXunlock, and DXtry_lock calls to return success immediately.
57 **/
58 
59 int DXcreate_lock(lock_type *l, char *name);
60 /**
61 \index{create\_lock}
62 Creates a lock.  In some systems, the lock variable itself is used as
63 a lock; in other systems, a handle to a lock is put in the lock
64 variable.  In either case, you must pass the address {\tt l} of the lock
65 variable to this routine.  Returns zero for failure, non-zero for
66 success.
67 **/
68 
69 int DXdestroy_lock(lock_type *l);
70 /**
71 \index{destroy\_lock}
72 Destroys the lock pointed to by {\tt l}.  The lock must be unlocked
73 before this call is made.  Returns zero for failure, non-zero for
74 success.
75 **/
76 
77 int DXlock(lock_type *l, int who);
78 /**
79 \index{DXlock}
80 If the lock pointed to by {\tt l} is currently unlocked, it is
81 locked by the current thread of execution.  If it is currently locked,
82 execution blocks until it becomes unlocked, and then it is locked by
83 the current thread of execution.  The {\tt who} variable may be recorded
84 in the lock for later matching by {\tt DXunlock()}.  Returns zero for failure,
85 non-zero for success.
86 **/
87 
88 int DXtry_lock(lock_type *l, int who);
89 /**
90 \index{try\_lock}
91 If the lock pointed to by {\tt l} is currently unlocked, it is locked
92 by the current thread of execution.  If it is currently locked, the
93 routine returns zero immediately.  The {\tt who} variable may be recorded in
94 the lock for later matching by {\tt DXunlock()}.  Returns zero for failure,
95 non-zero for success.
96 **/
97 
98 int DXunlock(lock_type *l, int who);
99 /**
100 \index{DXunlock}
101 Unlocks the lock pointed to by {\tt l}.  The {\tt who} parameter may be
102 matched against the {\tt who} parameter of the call that locked the lock.
103 (To avoid this issue, you may just uniformly specify {\tt who} of zero in
104 all calls.)  Returns zero for failure, non-zero for success.
105 **/
106 
107 int DXfetch_and_add(int *p, int value, lock_type *l, int who);
108 /**
109 \index{DXfetch_and_add}
110 On machines which have a hardware fetch and add instruction, this routine
111 increments the value at location {\tt p} by {\tt value}, and the lock and
112 who parameters are ignored.  On machines without this instruction, the lock
113 is used to serialize access to location p before incrementing the old value
114 at location p by value.  In both cases, the previous value is returned.
115 **/
116 
117 /*
118 \paragraph{Multi-processor support.}
119 Certain considerations apply when using the memory allocator in a
120 multi-processor environment.  In particular, forking must be done by
121 calling {\tt DXmemfork(childno)}. This call is intended for use only by
122 the executive, and is of no interest to module writers.
123 */
124 #if defined(DXD_WIN) && defined(small)     /*  ajay defined in RPCNDR.h on NT  as "char" ajay  */
125 #undef	small
126 #endif
127 
128 Error DXSetGlobalSize(int, int, int);
129 Error DXmemsize(ulong size);
130 /**
131 \index{DXSetGlobalSize}\index{DXmemsize}
132 Sets the maximum total size of the small-block global memory arena, the
133 threshhold block size between the small and large arenas, and the maximum
134 total size of the large-block global memory arena, in bytes.
135 **/
136 
137 Error DXinitdx(void);
138 /**
139 \index{initadx}
140 Initializes Data Explorer.  In general it is not necessary to make this call
141 becuase as the system will arrange to make it before anything which
142 requires initialization is done.  However, in a multi-processor
143 application it may be necessary to call it to ensure proper
144 initialization before forking (although using {\tt DXmemfork(childno)}
145 guarantees initialization before forking.)
146 **/
147 
148 Error DXsyncmem(void);
149 /**
150 \index{DXsyncmem}
151 In a multi-process environment, this call may be needed at fork/join
152 points to re-synchronize the shared arena between processors.  This
153 is intended for use only in the executive, and is of no interest to
154 module writers.
155 **/
156 
157 int DXmemfork(int childno);
158 /**
159 \index{DXmemfork}
160 This call must be used instead of {\tt fork()} to create a new process.
161 It has the same return codes as {\tt fork()}.  This call
162 is intended for use only in the executive, and is of no interest to
163 module writers.
164 **/
165 
166 #if defined(__cplusplus) || defined(c_plusplus)
167 }
168 #endif
169 
170 #include <stdarg.h>
171 
172 #if defined(__cplusplus) || defined(c_plusplus)
173 extern "C" {
174 #endif
175 
176 
177 void DXqmessage(char *who, char *message, va_list args);
178 void DXsqmessage(char *who, char *message, va_list args);
179 /**
180 \index{DXqmessage}\index{DXsqmessage}
181 These routines assume that the caller has already called va\_start and
182 will subsequently call va\_end (this is the style used by vsprintf).
183 They will format the message appropriately as per the above discussion
184 and then call DXqwrite to queue the message.
185 **/
186 
187 void DXqwrite(int fd, char *buf, int length);
188 void DXqflush(void);
189 /**
190 \index{DXqwrite}\index{DXqflush}
191 A message for the given file descriptor is queued.  All messages will
192 be flushed when DXqflush() is called.  DXqwrite() may do a DXqflush() and
193 directly output the message if this message is being produced by the
194 memory allocator; this is considered an emergency situation.
195 **/
196 
197 #endif /* _DXI_ADVANCED_H_ */
198 
199 #if defined(__cplusplus) || defined(c_plusplus)
200 }
201 #endif
202