fixed deliberate error for ax25 dx spots
[spider.git] / src / cmsg.c
1 /*
2  * cmsg.c
3  * 
4  * create and free message buffers
5  * 
6  * Copyright 1996 (c) D-J Koopman
7  * 
8  * $Header$
9  */
10
11
12 static char rcsid[] = "$Id$";
13
14 #include <time.h>
15 #include <stdlib.h>
16
17 #include "chain.h"
18 #include "cmsg.h"
19
20 long cmsg_count = 0;
21
22 #ifdef DB_CMSG
23 #include <malloc.h>
24 #include <stdio.h>
25
26
27 #define MAXSORT 20
28 #define INTERVAL 10
29 #define FN "msg_stats"
30
31 static struct {
32         long new;
33         long free;
34 } stats[MAXSORT+1];
35
36 static void store()
37 {
38         static time_t t;
39         time_t systime;
40         
41         time(&systime);
42         if (systime - t > INTERVAL) {
43                 FILE *f = fopen(FN, "w");
44                 if (f) {
45                         int i;
46                         struct mallinfo m;                      
47                         fprintf(f, "\nMSG STATISTICS\n");
48                         fprintf(f,   "==============\n\n");
49                         fprintf(f, "cmsg_count = %ld\n\n", cmsg_count);
50                         for (i = 0; i < MAXSORT+1; ++i) {
51                                 if (stats[i].new == 0 && stats[i].free == 0)
52                                         continue;
53                                 fprintf(f, "%d new: %ld free: %ld outstanding: %ld\n", i, stats[i].new, stats[i].free, stats[i].new-stats[i].free);
54                         }
55                         m = mallinfo();
56                         fprintf(f, "\nmalloc total arena used: %ld used: %ld free: %ld\n\n", m.arena, m.uordblks, m.fordblks);
57                         fclose(f);
58                 }
59                 t = systime;
60         }
61 }
62
63 void cmsg_clear_stats()
64 {
65         memset(stats, 0, sizeof stats);
66         store();
67 }
68
69 #endif
70
71 cmsg_t *cmsg_new(int size, int sort, void *pp)
72 {
73         cmsg_t *mp;
74         
75         mp = malloc(sizeof(cmsg_t) + size);
76         if (!mp)
77                 die("no room in cmsg_new");
78         mp->size = 0;
79         mp->sort = sort & CMSG_SORTMASK;
80         mp->portp = pp;
81         mp->state = mp->reply = 0;
82         mp->inp = mp->data;
83         mp->callback = 0;
84         ++cmsg_count;
85 #ifdef DB_CMSG
86         if (sort > MAXSORT)
87                 sort = MAXSORT;
88         ++stats[sort].new;      
89         store();
90 #endif
91         return mp;
92 }
93
94 void cmsg_send(reft *base, cmsg_t *mp, void (*callback)())
95 {
96         time(&mp->t);
97         mp->size = mp->inp - mp->data;     /* calc the real size */
98         mp->callback = callback;                   /* store the reply address */
99         chain_insert(base, mp);
100 #ifdef DB_CMSG
101         store();
102 #endif
103 }
104
105 void cmsg_priority_send(reft *base, cmsg_t *mp, void (*callback)())
106 {
107         time(&mp->t);
108         mp->size = mp->inp - mp->data;     /* calc the real size */
109         mp->callback = callback;                   /* store the reply address */
110         chain_add(base, mp);
111 #ifdef DB_CMSG
112         store();
113 #endif
114 }
115
116 /*
117  * get the next cmsg (from the front), this removes the message from the chain
118  */
119
120 cmsg_t *cmsg_next(reft *base)
121 {
122         cmsg_t *mp = chain_get_next(base, 0);
123         if (mp)
124                 chain_delete(mp);
125 #ifdef DB_CMSG
126         store();
127 #endif
128         return mp;
129 }
130
131 /*
132  * get the prev cmsg (from the back), this removes the message from the chain
133  */
134
135 cmsg_t *cmsg_prev(reft *base)
136 {
137         cmsg_t *mp = chain_get_prev(base, 0);
138         if (mp)
139                 chain_delete(mp);
140 #ifdef DB_CMSG
141         store();
142 #endif
143         return mp;
144 }
145
146 void cmsg_callback(cmsg_t *m, int reply)
147 {
148         if (m->callback)
149                 (m->callback)(m, reply);
150         cmsg_free(m);
151 }
152
153 void cmsg_free(cmsg_t *m)
154 {
155         --cmsg_count;
156 #ifdef DB_CMSG
157         if (m->sort > MAXSORT)
158                 m->sort = MAXSORT;
159         ++stats[m->sort].free;  
160         store();
161 #endif
162         free(m);
163 }
164
165 void cmsg_flush(reft *base, int reply)
166 {
167         cmsg_t *m;
168         
169         while (m = cmsg_next(base)) {
170                 cmsg_callback(m, reply);
171         }
172 #ifdef DB_CMSG
173         store();
174 #endif
175 }               
176
177 /*
178  * 
179  * $Log$
180  * Revision 1.1  2000-03-26 00:03:30  djk
181  * first cut of client
182  *
183  * Revision 1.12  1998/05/05 14:01:27  djk
184  * Tidied up various global variables in the hope that there is likely
185  * to be less undefined interaction between modules.
186  * Added some extra LINUX debugging to check for possible cmsg memory leaks.
187  *
188  * Revision 1.11  1998/01/02 19:39:58  djk
189  * made various changes to cope with glibc
190  * fixed problem with extended status in etsi_router
191  *
192  * Revision 1.10  1997/06/13 16:51:17  djk
193  * fixed various library problems
194  * got the taipstack and hayes to the point of half duplex reliability
195  * hayes now successfully communicates with taiptest and has part of the
196  * command level taip stuff in.
197  *
198  * Revision 1.9  1997/05/20 20:45:14  djk
199  * The 1.22 version more or less unchanged
200  *
201  * Revision 1.8  1997/03/25 18:12:55  djk
202  * dunno
203  *
204  * Revision 1.7  1997/03/19 09:57:28  djk
205  * added a count to check for leaks
206  *
207  * Revision 1.6  1997/02/13 17:02:04  djk
208  * forgotten?
209  *
210  * Revision 1.5  1997/02/04 17:47:04  djk
211  * brought into line with public2
212  *
213  * Revision 1.4  1997/02/04 01:27:37  djk
214  * altered size semantics on create (size now = 0 not creation size)
215  *
216  * Revision 1.3  1997/01/20 22:29:27  djk
217  * added status back
218  *
219  * Revision 1.2  1997/01/13 23:34:29  djk
220  * The first working test version of smsd
221  *
222  * Revision 1.1  1997/01/03 23:42:21  djk
223  * added a general message handling module (still developing)
224  * added parity handling to ser.c
225  *
226  */