Anonymous user
Generator/Exponential: Difference between revisions
→{{libheader|libco}}: Add some ugly code to check for memory allocation, and to free memory. C is being an awful language.
(→{{header|E}}: Add C using libco.) |
(→{{libheader|libco}}: Add some ugly code to check for memory allocation, and to free memory. C is being an awful language.) |
||
Line 22:
<lang c>#include <inttypes.h> /* int64_t, PRId64 */
#include <stdlib.h> /* exit() */
#include <stdio.h> /* printf() */
#include <libco.h> /*
Line 30 ⟶ 31:
/* A generator that yields values of type int64_t. */
struct gen64 {
cothread_t giver; /* this
cothread_t taker; /* this
int64_t given;
void (*free)(struct gen64 *);
void *garbage;
};
Line 50 ⟶ 53:
co_switch(gen->giver);
return gen->given;
}
static void
gen64_free(struct gen64 *gen)
{
co_delete(gen->giver);
}
Line 55 ⟶ 64:
/*
* Creates a
* will enter the
* from the global variable struct gen64 *entry64.
* Use gen->free(gen) to free the cothread.
*/
inline void
gen64_init(struct gen64 *gen, void (*entry)(void))
{
if ((gen->giver = co_create(4096, entry)
/* Perhaps malloc() failed */
fputs("co_create: Cannot create cothread\n", stderr);
exit(1);
}
gen->free = gen64_free;
entry64 = gen;
}
#define ENTRY(name, code) static void name(void) { code; }▼
/*
Line 96 ⟶ 109:
}
/* stuff for squares_without_cubes() */
▲#define ENTRY(name, code) static void name(void) { code; }
ENTRY(enter_squares, powers(entry64, 2))
ENTRY(enter_cubes, powers(entry64, 3))
struct swc {
struct gen64 cubes;
struct gen64 squares;
void (*old_free)(struct gen64 *);
};
static void
swc_free(struct gen64 *gen)
{
struct swc *f = gen->garbage;
f->cubes.free(&f->cubes);
f->squares.free(&f->squares);
f->old_free(gen);
}
/*
Line 106 ⟶ 136:
squares_without_cubes(struct gen64 *gen)
{
struct
int64_t c, s;
gen64_init(&f.cubes, enter_cubes);
c = next64(&f.cubes);
gen64_init(&f.squares, enter_squares);▼
s = next64(&f.squares);▼
/* Allow other cothread to free this generator. */
▲ gen64_init(&squares, enter_squares);
f.old_free = gen->free;
▲ s = next64(&squares);
gen->garbage = &f;
gen->free = swc_free;
for (;;) {
Line 119 ⟶ 154:
yield64(gen, s);
while (c <= s)
c = next64(&f.cubes);
s = next64(&f.squares);
}
/* NOTREACHED */
Line 145 ⟶ 180:
printf("%" PRId64 "\n", next64(&gen));
gen.free(&gen); /* Free memory. */
▲ /*
return 0;
}</lang>
|