about summary refs log tree commit diff stats
path: root/util.h
blob: 8ba444b0d845d6217d6da9b2009fe661c7458111 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 * See LICENSE file for license details.
 */

extern void error(char *errstr, ...);
extern void *emallocz(unsigned int size);
extern void *emalloc(unsigned int size);
extern void *erealloc(void *ptr, unsigned int size);
extern char *estrdup(const char *str);
#define eassert(a) do { \
		if(!(a)) \
			failed_assert(#a, __FILE__, __LINE__); \
	} while (0)
void failed_assert(char *a, char *file, int line);
void swap(void **p1, void **p2);
an 'def'' href='/akkartik/mu/commit/channel.mu?h=main&id=0ca35d02df358b73f4e2c6c665226d2d56c61fdd'>0ca35d02 ^
f192d655 ^
d1c12218 ^
d4b4d018 ^
f192d655 ^

5b698455 ^
f192d655 ^
afadac25 ^
f192d655 ^
7d2c2d55 ^
4b62edd8 ^
7d2c2d55 ^
be440cb6 ^
f192d655 ^


0ca35d02 ^
8b00ce3f ^
68c45cb8 ^
f192d655 ^
ea0d661b ^



f192d655 ^
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
                    
                                       
                                                               
                                      
         
                               
         

                                                    
                                                  
                                    
                                                  
                             

                                                                         

                                                                             
                                                                                            
                                          
          


   
                    
                                             
                                                               
                                      

                                          
                                                                            
                                            
                                                               
                                                  
                                    
                                                   
                             
          


   
                
                                                               
                                                  
                                                                  



                                                                                                   
  
(function producer [
  ; produce numbers 1 to 5 on a channel
  (default-space:space-address <- new space:literal 30:literal)
  (chan:channel-address <- next-input)
  ; n = 0
  (n:integer <- copy 0:literal)
  { begin
    (done?:boolean <- less-than n:integer 5:literal)
    (break-unless done?:boolean)
    ; other threads might get between these prints
    ($print (("produce: " literal)))
    (print-integer nil:literal/terminal n:integer)
    ($print (("\n" literal)))
    ; 'box' n into a dynamically typed 'tagged value' because that's what
    ; channels take
    (n2:integer <- copy n:integer)
    (n3:tagged-value-address <- init-tagged-value integer:literal n2:integer)
    (chan:channel-address/deref <- write chan:channel-address n3:tagged-value-address/deref)
    (n:integer <- add n:integer 1:literal)
    (loop)
  }
])

(function consumer [
  ; consume and print integers from a channel
  (default-space:space-address <- new space:literal 30:literal)
  (chan:channel-address <- next-input)
  { begin
    ; read a tagged value from the channel
    (x:tagged-value chan:channel-address/deref <- read chan:channel-address)
    ; unbox the tagged value into an integer
    (n2:integer <- maybe-coerce x:tagged-value integer:literal)
    ; other threads might get between these prints
    ($print (("consume: " literal)))
    (print-integer nil:literal/terminal n2:integer)
    ($print (("\n" literal)))
    (loop)
  }
])

(function main [
  (default-space:space-address <- new space:literal 30:literal)
  (chan:channel-address <- init-channel 3:literal)
  ; create two background 'routines' that communicate by a channel
  (routine1:integer <- fork consumer:fn nil:literal/globals nil:literal/limit chan:channel-address)
  (routine2:integer <- fork producer:fn nil:literal/globals nil:literal/limit chan:channel-address)
  (sleep until-routine-done:literal routine1:integer)
  (sleep until-routine-done:literal routine2:integer)
])