123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- /**
- * \file worker.c
- *
- * \brief Implementation of the client for parallel
- * computing of r.li raster analysis
- *
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
- *
- * \author Claudio Porta & Lucio Davide Spano
- *
- * \version 1.0
- *
- */
- #include <stdlib.h>
- #include <stddef.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <dirent.h>
- #include <errno.h>
- #include <math.h>
- #ifdef __MINGW32__
- #include <process.h>
- #else
- #include <sys/wait.h>
- #endif
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include <grass/glocale.h>
- #include "daemon.h"
- #include "defs.h"
- #define CACHESIZE 4194304
- static int fd, aid;
- static int erease_mask = 0, data_type = 0;
- static int cache_rows, used = 0;
- static struct area_entry * ad;
- static double result;
- static struct Cell_head hd;
- static cell_manager cm;
- static dcell_manager dm;
- static fcell_manager fm;
- static char *raster;
- static char **parameters;
- static int (*func) (int, char **, struct area_entry *, double *);
- void worker_init(char *r, int f(int, char **, struct area_entry *, double *), char **p)
- {
- cm = G_malloc(sizeof(struct cell_memory_entry));
- fm = G_malloc(sizeof(struct fcell_memory_entry));
- dm = G_malloc(sizeof(struct dcell_memory_entry));
- ad = G_malloc(sizeof(struct area_entry));
- raster = r;
- parameters = p;
- func = f;
- /* open raster map */
- fd = Rast_open_old(raster, "");
- Rast_get_cellhd(raster, "", &hd);
- /* read data type to allocate cache */
- data_type = Rast_map_type(raster, "");
- /* calculate rows in cache */
- switch (data_type) {
- case CELL_TYPE:{
- cache_rows = CACHESIZE / (hd.cols * sizeof(CELL));
- cm->cache = G_malloc(cache_rows * sizeof(CELL *));
- cm->contents = G_malloc(cache_rows * sizeof(int));
- cm->used = 0;
- cm->contents[0] = -1;
- } break;
- case DCELL_TYPE:{
- cache_rows = CACHESIZE / (hd.cols * sizeof(DCELL));
- dm->cache = G_malloc(cache_rows * sizeof(DCELL *));
- dm->contents = G_malloc(cache_rows * sizeof(int));
- dm->used = 0;
- dm->contents[0] = -1;
- } break;
- case FCELL_TYPE:{
- cache_rows = CACHESIZE / (hd.cols * sizeof(FCELL));
- fm->cache = G_malloc(cache_rows * sizeof(FCELL *));
- fm->contents = G_malloc(cache_rows * sizeof(int));
- fm->used = 0;
- fm->contents[0] = -1;
- } break;
- }
- ad->data_type = data_type;
- ad->cm = cm;
- ad->fm = fm;
- ad->dm = dm;
- }
- void worker_process(msg * ret, msg * m)
- {
- switch (m->type) {
- case AREA:
- aid = m->f.f_a.aid;
- ad->x = m->f.f_a.x;
- ad->y = m->f.f_a.y;
- ad->rl = m->f.f_a.rl;
- ad->cl = m->f.f_a.cl;
- ad->raster = raster;
- ad->mask = -1;
- break;
- case MASKEDAREA:
- aid = m->f.f_ma.aid;
- ad->x = m->f.f_ma.x;
- ad->y = m->f.f_ma.y;
- ad->rl = m->f.f_ma.rl;
- ad->cl = m->f.f_ma.cl;
- ad->raster = raster;
- /* mask preprocessing */
- ad->mask_name = mask_preprocessing(m->f.f_ma.mask,
- raster, ad->rl, ad->cl);
- if (ad->mask_name == NULL) {
- G_message(_("unable to open <%s> mask ... continuing without!"),
- m->f.f_ma.mask);
- ad->mask = -1;
- }
- else {
- if (strcmp(m->f.f_ma.mask, ad->mask_name) != 0)
- /* temporary mask created */
- erease_mask = 1;
- ad->mask = open(ad->mask_name, O_WRONLY, 0755);
- if (ad->mask == -1) {
- G_message(_("unable to open <%s> mask ... continuing without!"),
- m->f.f_ma.mask);
- }
- }
- break;
- default:
- G_fatal_error("Program error, worker() type=%d", m->type);
- break;
- }
- /* memory menagement */
- if (ad->rl > used) {
- /* allocate cache */
- int i;
- switch (data_type) {
- case CELL_TYPE:{
- for (i = 0; i < (ad->rl - used); i++) {
- cm->cache[used + i] = Rast_allocate_c_buf();
- }
- }
- break;
- case DCELL_TYPE:{
- for (i = 0; i < ad->rl - used; i++) {
- dm->cache[used + i] = Rast_allocate_d_buf();
- }
- }
- break;
- case FCELL_TYPE:{
- for (i = 0; i < ad->rl - used; i++) {
- fm->cache[used + i] = Rast_allocate_f_buf();
- }
- }
- break;
- }
- cm->used = ad->rl;
- dm->used = ad->rl;
- fm->used = ad->rl;
- used = ad->rl;
- }
- /* calculate function */
- if (func(fd, parameters, ad, &result) == RLI_OK) {
- /* success */
- ret->type = DONE;
- ret->f.f_d.aid = aid;
- ret->f.f_d.pid = 0;
- ret->f.f_d.res = result;
- }
- else {
- /* fail */
- ret->type = ERROR;
- ret->f.f_e.aid = aid;
- ret->f.f_e.pid = 0;
- }
- if (erease_mask == 1) {
- erease_mask = 0;
- unlink(ad->mask_name);
- }
- }
- void worker_end(void)
- {
- /* close raster map */
- Rast_close(fd);
- }
- char *mask_preprocessing(char *mask, char *raster, int rl, int cl)
- {
- const char *tmp_file;
- struct Cell_head cell, oldcell;
- int mask_fd, old_fd, *buf, i, j;
- CELL *old;
- double add_row, add_col;
- buf = G_malloc(cl * sizeof(int));
- G_debug(3, "daemon mask preproc: raster=[%s] mask=[%s] rl=%d cl=%d",
- raster, mask, rl, cl);
- /* open raster */
- Rast_get_cellhd(raster, "", &cell);
- /* open raster */
- Rast_get_cellhd(mask, "", &oldcell);
- add_row = 1.0 * oldcell.rows / rl;
- add_col = 1.0 * oldcell.cols / cl;
- tmp_file = G_tempfile();
- mask_fd = open(tmp_file, O_RDWR | O_CREAT, 0755);
- old_fd = Rast_open_old(mask, "");
- old = Rast_allocate_c_buf();
- for (i = 0; i < rl; i++) {
- int riga;
- riga = (int)rint(i * add_row);
- Rast_get_c_row_nomask(old_fd, old, riga);
- for (j = 0; j < cl; j++) {
- int colonna;
- colonna = (int)rint(j * add_col);
- buf[j] = old[colonna];
- }
- if (write(mask_fd, buf, cl * sizeof(int)) < 0)
- return NULL;
- }
- close(mask_fd);
- return G_store(tmp_file);
- }
- CELL *RLI_get_cell_raster_row(int fd, int row, struct area_entry *ad)
- {
- int hash;
- hash = row % ad->rl;
- if (ad->cm->contents[hash] == row)
- return ad->cm->cache[hash];
- else {
- Rast_get_row(fd, ad->cm->cache[hash], row, CELL_TYPE);
- ad->cm->contents[hash] = row;
- return ad->cm->cache[hash];
- }
- }
- DCELL *RLI_get_dcell_raster_row(int fd, int row, struct area_entry *ad)
- {
- int hash;
- hash = row % ad->rl;
- if (ad->dm->contents[hash] == row)
- return ad->dm->cache[hash];
- else {
- Rast_get_row(fd, ad->dm->cache[hash], row, DCELL_TYPE);
- ad->dm->contents[hash] = row;
- return ad->dm->cache[hash];
- }
- }
- FCELL *RLI_get_fcell_raster_row(int fd, int row, struct area_entry *ad)
- {
- int hash;
- hash = row % ad->rl;
- if (ad->fm->contents[hash] == row)
- return ad->fm->cache[hash];
- else {
- Rast_get_row(fd, ad->fm->cache[hash], row, FCELL_TYPE);
- ad->fm->contents[hash] = row;
- return ad->fm->cache[hash];
- }
- }
|