about summary refs log tree commit diff stats
path: root/073scheduler.cc
Commit message (Collapse)AuthorAgeFilesLines
* 4413Kartik Agaram2018-07-251-1/+1
| | | | | Never mind, let's drop unused/vestigial altogether. Use absence of names to signal unused arguments.
* 4242 - get rid of refcounts entirelyKartik Agaram2018-05-121-2/+1
| | | | | | | | | We're going to lean back into the experiment of commit 4179 back in Jan. If we delete memory it's up to us to ensure no pointers into it survive. Since deep-copy depends on our refcounting infrastructure, it's gone as well. So we're going to have to start watching out for pointers shared over channels.
* 4235 - fix a build issue for Apple clang 900.0.38Kartik K. Agaram2018-04-201-1/+1
| | | | | | | The trouble with rewriting 'unused' to '__attribute__(unused)' is that if we happen to deliberately introduce '__attribute__(unused)' somehow, say in the standard headers, then it gets expanded twice to '__attribute__(__attribute__(unused))'. So we switch to a synonym.
* 4179 - experiment: rip out memory reclamationKartik K. Agaram2018-01-031-69/+0
| | | | | | | | | | | | | | | | | | | | | I have a plan for a way to avoid use-after-free errors without all the overheads of maintaining refcounts. Has the nice side-effect of requiring manual memory management. The Mu way is to leak memory by default and build tools to help decide when and where to expend effort plugging memory leaks. Arguably programs should be distributed with summaries of their resource use characteristics. Eliminating refcount maintenance reduces time to run tests by 30% for `mu edit`: this commit parent mu test: 3.9s 4.5s mu test edit: 2:38 3:48 Open questions: - making reclamation easier; some sort of support for destructors - reclaiming local scopes (which are allocated on the heap) - should we support automatically reclaiming allocations inside them?
* 4104Kartik K. Agaram2017-11-031-1/+1
| | | | | Stop hardcoding Max_depth everywhere; we had a default value for a reason but then we forgot all about it.
* 4099Kartik K. Agaram2017-11-011-1/+1
| | | | | | | | | | | | | | Generalize commit 4089 to arbitrary closures, and not just the current 'space' or call frame. Now we should be treating spaces just like any other data structure, and reclaiming all addresses inside them when we need to. The cost: all spaces must now specify what recipe generated them (so they know how to interpret the array of locations) using the /names property. We can probably make this ergonomic with a little 'type inference'. But at least things are safe now.
* 3993Kartik K. Agaram2017-09-131-19/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fully isolate routines from their arguments. I still need exceptions for containers that are *designed* to be shared between routines. The primary such case is channels; we need some way to share them between routines, and if we deep-copy them that defeats their entire purpose. A milder case is the use of fake file-systems in tests, though that's a hint that there'll be more of these as the OS gets more fleshed out. The pattern seems to be that we need to not deep-copy containers that contain lock fields, and so their operations internally do their own locking. We may have to stop hard-coding the list of exceptions and allow people to define new ones. Perhaps don't deep-copy any container with metadata of 'shared', and then ensure that get-location is only ever called on shared containers. This still isn't absolutely ironclad. People can now store something into a channel and then pass it into a routine to share arbitrary data. But perhaps the goal isn't to be ironclad, just to avoid easy mistakes. I'd still want an automated check for this, though. Some way to highlight it as an unsafe pattern. This completes step 1 in the plan of commit 3992 for making continuations safe.
* 3992Kartik K. Agaram2017-09-101-2/+1
|
* 3991 - start work on making continuations safeKartik K. Agaram2017-09-101-0/+706
Plan: 1. Fix a hole where addresses are shared between routines when passed in as arguments to `start-running`. 2. Switch to a new approach to refcount management: instead of updating refcounts when writing products of instructions by default, increment refcounts inside instructions by default and decrement refcounts in caller. More details in future when I actually implement this. 3. Now we shouldn't need a distinction between `new-default-space` and `local-scope`, and all functions can simply decrement refcounts of their default-space, consistently handling any refcounts in the space. At this point if all goes well, continuations should be safe! This commit is just preparation for step 1.
dd24b8a9534256f7efd45'>5898da96 ^
ae08e820 ^




5898da96 ^

















ae08e820 ^




5898da96 ^

















ae08e820 ^




5898da96 ^

















ae08e820 ^




5898da96 ^

















ae08e820 ^




5898da96 ^










80acfdae ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407







                   
                         












                                                                             
                           













                                                                             
                           































































                                                                           










                                                                           






                                                                           




                                                                                 

















                                                                           




                                                                                           

















                                                                           



                                                                                           
















                                                                           


                                                                                     















                                                                           

                                                                                  














                                                                           
                                                                                  


























                                                                           
 













































                                                                           




                                                                                           

















                                                                         




                                                                                           

















                                                                         




                                                                                           

















                                                                         




                                                                                           

















                                                                         




                                                                                           










                                                      
 
#include <glib.h>
#include <stdarg.h>
#include <string.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>

#include "xmpp/contact.h"

void contact_in_group(void **state)
{
    GSList *groups = NULL;
    groups = g_slist_append(groups, strdup("somegroup"));
    PContact contact = p_contact_new("bob@server.com", "bob", groups, "both",
        "is offline", FALSE);

    gboolean result = p_contact_in_group(contact, "somegroup");

    assert_true(result);

    p_contact_free(contact);
//    g_slist_free(groups);
}

void contact_not_in_group(void **state)
{
    GSList *groups = NULL;
    groups = g_slist_append(groups, strdup("somegroup"));
    PContact contact = p_contact_new("bob@server.com", "bob", groups, "both",
        "is offline", FALSE);

    gboolean result = p_contact_in_group(contact, "othergroup");

    assert_false(result);

    p_contact_free(contact);
//    g_slist_free(groups);
}

void contact_name_when_name_exists(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    const char *name = p_contact_name_or_jid(contact);

    assert_string_equal("bob", name);

    p_contact_free(contact);
}

void contact_jid_when_name_not_exists(void **state)
{
    PContact contact = p_contact_new("bob@server.com", NULL, NULL, "both",
        "is offline", FALSE);

    const char *jid = p_contact_name_or_jid(contact);

    assert_string_equal("bob@server.com", jid);

    p_contact_free(contact);
}

void contact_string_when_name_exists(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    char *str = p_contact_create_display_string(contact, "laptop");

    assert_string_equal("bob (laptop)", str);

    p_contact_free(contact);
    free(str);
}

void contact_string_when_name_not_exists(void **state)
{
    PContact contact = p_contact_new("bob@server.com", NULL, NULL, "both",
        "is offline", FALSE);

    char *str = p_contact_create_display_string(contact, "laptop");

    assert_string_equal("bob@server.com (laptop)", str);

    p_contact_free(contact);
    free(str);
}

void contact_string_when_default_resource(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    char *str = p_contact_create_display_string(contact, "__prof_default");

    assert_string_equal("bob", str);

    p_contact_free(contact);
    free(str);
}

void contact_presence_offline(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("offline", presence);

    p_contact_free(contact);
}

void contact_presence_uses_highest_priority(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource10 = resource_new("resource10", RESOURCE_ONLINE, NULL, 10);
    Resource *resource20 = resource_new("resource20", RESOURCE_CHAT, NULL, 20);
    Resource *resource30 = resource_new("resource30", RESOURCE_AWAY, NULL, 30);
    Resource *resource1 = resource_new("resource1", RESOURCE_XA, NULL, 1);
    Resource *resource2 = resource_new("resource2", RESOURCE_DND, NULL, 2);
    p_contact_set_presence(contact, resource10);
    p_contact_set_presence(contact, resource20);
    p_contact_set_presence(contact, resource30);
    p_contact_set_presence(contact, resource1);
    p_contact_set_presence(contact, resource2);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("away", presence);

    p_contact_free(contact);
}

void contact_presence_chat_when_same_prioroty(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10);
    Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_chat);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("chat", presence);

    p_contact_free(contact);
}

void contact_presence_online_when_same_prioroty(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("online", presence);

    p_contact_free(contact);
}

void contact_presence_away_when_same_prioroty(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("away", presence);

    p_contact_free(contact);
}

void contact_presence_xa_when_same_prioroty(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("xa", presence);

    p_contact_free(contact);
}

void contact_presence_dnd(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_dnd);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("dnd", presence);

    p_contact_free(contact);
}

void contact_subscribed_when_to(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "to",
        "is offline", FALSE);

    gboolean result = p_contact_subscribed(contact);

    assert_true(result);

    p_contact_free(contact);
}

void contact_subscribed_when_both(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "both",
        "is offline", FALSE);

    gboolean result = p_contact_subscribed(contact);

    assert_true(result);

    p_contact_free(contact);
}

void contact_not_subscribed_when_from(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, "from",
        "is offline", FALSE);

    gboolean result = p_contact_subscribed(contact);

    assert_false(result);

    p_contact_free(contact);
}

void contact_not_subscribed_when_no_subscription_value(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL,
        "is offline", FALSE);

    gboolean result = p_contact_subscribed(contact);

    assert_false(result);

    p_contact_free(contact);
}

void contact_not_available(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL,
        "is offline", FALSE);

    gboolean result = p_contact_is_available(contact);

    assert_false(result);

    p_contact_free(contact);
}

void contact_not_available_when_highest_priority_away(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL,
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10);
    Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 20);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_chat);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    gboolean result = p_contact_is_available(contact);

    assert_false(result);

    p_contact_free(contact);
}

void contact_not_available_when_highest_priority_xa(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL,
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10);
    Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 20);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_chat);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    gboolean result = p_contact_is_available(contact);

    assert_false(result);

    p_contact_free(contact);
}

void contact_not_available_when_highest_priority_dnd(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL,
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10);
    Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 20);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_chat);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    gboolean result = p_contact_is_available(contact);

    assert_false(result);

    p_contact_free(contact);
}

void contact_available_when_highest_priority_online(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL,
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 20);
    Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_chat);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    gboolean result = p_contact_is_available(contact);

    assert_true(result);

    p_contact_free(contact);
}

void contact_available_when_highest_priority_chat(void **state)
{
    PContact contact = p_contact_new("bob@server.com", "bob", NULL, NULL,
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10);
    Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 20);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_chat);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    gboolean result = p_contact_is_available(contact);

    assert_true(result);

    p_contact_free(contact);
}