app/paint_funcs.c app/pixel_processor.c app/tile.c app/tile_cache.c

2001-01-23  Sven Neumann  <sven@gimp.org>

	* app/paint_funcs.c
	* app/pixel_processor.c
	* app/tile.c
	* app/tile_cache.c
	* app/tile_manager.c
	* app/tile_pvt.h
	* app/tile_swap.[ch]: cleanups, indentation
This commit is contained in:
Sven Neumann 2001-01-23 14:21:37 +00:00 committed by Sven Neumann
parent b102101e94
commit 6c3ef74547
17 changed files with 678 additions and 578 deletions

View File

@ -1,3 +1,13 @@
2001-01-23 Sven Neumann <sven@gimp.org>
* app/paint_funcs.c
* app/pixel_processor.c
* app/tile.c
* app/tile_cache.c
* app/tile_manager.c
* app/tile_pvt.h
* app/tile_swap.[ch]: cleanups, indentation
2001-01-23 Sven Neumann <sven@gimp.org>
* app/convert.c

View File

@ -20,10 +20,6 @@
#include "config.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef ENABLE_MP
#include <pthread.h>
#define IF_THREAD(statement) statement
@ -31,9 +27,9 @@
#define IF_THREAD(statement)
#endif /* ENABLE_MP */
#include <gtk/gtk.h>
#include <glib.h>
#include <apptypes.h>
#include "apptypes.h"
#include "pixel_processor.h"
#include "pixel_region.h"
@ -75,7 +71,7 @@ struct _PixelProcessor
IF_THREAD(
static void *
do_parallel_regions (PixelProcessor *p_s)
do_parallel_regions (PixelProcessor *p_s)
{
PixelRegion tr[4];
int ntiles = 0;
@ -161,7 +157,7 @@ do_parallel_regions (PixelProcessor *p_s)
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
p_s->nthreads--;
/* fprintf(stderr, "processed %d tiles\n", ntiles); */
pthread_mutex_unlock(&p_s->mutex);
return NULL;
@ -176,30 +172,33 @@ do_parallel_regions (PixelProcessor *p_s)
* configured --with-mp
*/
static void *
do_parallel_regions_single(PixelProcessor *p_s)
static gpointer
do_parallel_regions_single (PixelProcessor *p_s)
{
int cont = 1;
gint cont = 1;
do
{
switch(p_s->n_regions)
switch (p_s->n_regions)
{
case 1:
((p1_func)p_s->f)(p_s->data,
p_s->r[0]);
break;
case 2:
((p2_func)p_s->f)(p_s->data,
p_s->r[0],
p_s->r[1]);
break;
case 3:
((p3_func)p_s->f)(p_s->data,
p_s->r[0],
p_s->r[1],
p_s->r[2]);
break;
case 4:
((p4_func)p_s->f)(p_s->data,
p_s->r[0],
@ -207,180 +206,207 @@ do_parallel_regions_single(PixelProcessor *p_s)
p_s->r[2],
p_s->r[3]);
break;
default:
g_message("do_parallel_regions_single: Bad number of regions %d\n",
p_s->n_regions);
}
if (p_s->progress_report_func)
if (!p_s->progress_report_func(p_s->progress_report_data,
p_s->r[0]->x, p_s->r[0]->y,
p_s->r[0]->w, p_s->r[0]->h))
if (!p_s->progress_report_func (p_s->progress_report_data,
p_s->r[0]->x, p_s->r[0]->y,
p_s->r[0]->w, p_s->r[0]->h))
cont = 0;
} while (cont && p_s->PRI &&
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
}
while (cont && p_s->PRI &&
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
return NULL;
}
#define MAX_THREADS 30
static void
pixel_regions_do_parallel(PixelProcessor *p_s)
pixel_regions_do_parallel (PixelProcessor *p_s)
{
IF_THREAD(
int nthreads;
nthreads = MIN(num_processors, MAX_THREADS);
IF_THREAD(
gint nthreads;
nthreads = MIN (num_processors, MAX_THREADS);
/* make sure we have at least one tile per thread */
nthreads = MIN(nthreads,
(p_s->PRI->region_width * p_s->PRI->region_height)
/(TILE_WIDTH*TILE_HEIGHT));
/* make sure we have at least one tile per thread */
nthreads = MIN (nthreads,
(p_s->PRI->region_width * p_s->PRI->region_height)
/ (TILE_WIDTH * TILE_HEIGHT));
if (nthreads > 1)
if (nthreads > 1)
{
int i;
gint i;
pthread_t threads[MAX_THREADS];
pthread_attr_t pthread_attr;
pthread_attr_init (&pthread_attr);
for (i = 0; i < nthreads; i++)
{
pthread_create (&threads[i], &pthread_attr,
(void *(*)(void *)) do_parallel_regions,
p_s);
}
{
pthread_create (&threads[i], &pthread_attr,
(void *(*)(void *)) do_parallel_regions,
p_s);
}
for (i = 0; i < nthreads; i++)
{
int ret;
if ((ret = pthread_join(threads[i], NULL)))
{
fprintf(stderr, "pixel_regions_do_parallel:: pthread_join returned: %d\n", ret);
}
}
{
gint ret;
if ((ret = pthread_join(threads[i], NULL)))
{
g_printerr ("pixel_regions_do_parallel:: pthread_join returned: %d\n", ret);
}
}
if (p_s->nthreads != 0)
fprintf(stderr, "pixel_regions_do_prarallel: we lost a thread\n");
g_printerr ("pixel_regions_do_prarallel: we lost a thread\n");
}
else
)
do_parallel_regions_single(p_s);
else
)
do_parallel_regions_single (p_s);
}
static PixelProcessor *
pixel_regions_real_process_parallel(p_func f, void *data,
ProgressReportFunc report_func,
void *report_data,
int num_regions, va_list ap)
pixel_regions_real_process_parallel (p_func f,
gpointer data,
ProgressReportFunc report_func,
gpointer report_data,
gint num_regions,
va_list ap)
{
int i;
gint i;
PixelProcessor *p_s;
p_s = g_new(PixelProcessor, 1);
p_s = g_new (PixelProcessor, 1);
for (i = 0; i < num_regions; i++)
p_s->r[i] = va_arg (ap, PixelRegion *);
switch(num_regions)
{
case 1:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
p_s->r[0]);
break;
case 2:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
p_s->r[0],
p_s->r[1]);
{
case 1:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
p_s->r[0]);
break;
case 2:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
p_s->r[0],
p_s->r[1]);
break;
case 3:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
p_s->r[0],
p_s->r[1],
p_s->r[2]);
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
p_s->r[0],
p_s->r[1],
p_s->r[2]);
break;
case 4:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
p_s->r[0],
p_s->r[1],
p_s->r[2],
p_s->r[3]);
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
p_s->r[0],
p_s->r[1],
p_s->r[2],
p_s->r[3]);
break;
default:
g_message("pixel_regions_real_process_parallel: Bad number of regions %d\n",
p_s->n_regions);
g_message ("pixel_regions_real_process_parallel: Bad number of regions %d\n",
p_s->n_regions);
}
if (!p_s->PRI)
{
pixel_processor_free(p_s);
return NULL;
}
{
pixel_processor_free (p_s);
return NULL;
}
/* Why would we wan't to set dirty_tiles to 0 here? */
/* IF_THREAD(p_s->PRI->dirty_tiles = 0;) */
p_s->f = f;
p_s->data = data;
p_s->n_regions = num_regions;
IF_THREAD(pthread_mutex_init(&(p_s->mutex), NULL);)
IF_THREAD (pthread_mutex_init(&(p_s->mutex), NULL);)
p_s->nthreads = 0;
p_s->progress_report_data = report_data;
p_s->progress_report_func = report_func;
pixel_regions_do_parallel(p_s);
pixel_regions_do_parallel (p_s);
if (p_s->PRI)
return p_s;
pixel_processor_free (p_s);
return NULL;
}
void
pixel_regions_process_parallel(p_func f, void *data, int num_regions, ...)
pixel_regions_process_parallel (p_func f,
gpointer data,
gint num_regions,
...)
{
va_list va;
va_start (va, num_regions);
pixel_regions_real_process_parallel(f, data, NULL, NULL, num_regions, va);
pixel_regions_real_process_parallel (f, data, NULL, NULL, num_regions, va);
va_end (va);
}
PixelProcessor *
pixel_regions_process_parallel_progress(p_func f, void *data,
ProgressReportFunc progress_func,
void *progress_data, int num_regions,
...)
pixel_regions_process_parallel_progress (p_func f,
gpointer data,
ProgressReportFunc progress_func,
gpointer progress_data,
gint num_regions,
...)
{
PixelProcessor *ret;
va_list va;
va_start (va, num_regions);
va_list va;
ret = pixel_regions_real_process_parallel(f, data,
progress_func, progress_data,
num_regions, va);
va_start (va, num_regions);
ret = pixel_regions_real_process_parallel (f, data,
progress_func, progress_data,
num_regions, va);
va_end (va);
return ret;
}
void
pixel_processor_stop(PixelProcessor *pp)
pixel_processor_stop (PixelProcessor *pp)
{
if (!pp)
return;
if (pp->PRI)
{
pixel_regions_process_stop (pp->PRI);
pp->PRI = NULL;
}
pixel_processor_free(pp);
{
pixel_regions_process_stop (pp->PRI);
pp->PRI = NULL;
}
pixel_processor_free (pp);
}
PixelProcessor *
pixel_processor_cont(PixelProcessor *pp)
pixel_processor_cont (PixelProcessor *pp)
{
pixel_regions_do_parallel(pp);
pixel_regions_do_parallel (pp);
if (pp->PRI)
return pp;
pixel_processor_free (pp);
return NULL;
}
@ -388,7 +414,7 @@ void
pixel_processor_free (PixelProcessor *pp)
{
if (pp->PRI)
pixel_processor_stop(pp);
pixel_processor_stop (pp);
else
g_free(pp);
}

View File

@ -18,7 +18,6 @@
#include "config.h"
#include <stdio.h>
#ifdef USE_PTHREADS
#include <pthread.h>
#endif
@ -37,23 +36,28 @@
/* This is the percentage of the maximum cache size that should be cleared
* from the cache when an eviction is necessary
*/
#define FREE_QUANTUM 0.1
#define FREE_QUANTUM 0.1
static void tile_cache_init (void);
static gint tile_cache_zorch_next (void);
static void tile_cache_flush_internal (Tile *tile);
#define IDLE_SWAPPER_TIMEOUT 250
static void tile_cache_init (void);
static gint tile_cache_zorch_next (void);
static void tile_cache_flush_internal (Tile *tile);
#ifdef USE_PTHREADS
static void* tile_idle_thread (void *);
static gpointer tile_idle_thread (gpointer data);
#else
static gint tile_idle_preswap (gpointer);
static gint tile_idle_preswap (gpointer data);
#endif
static int initialize = TRUE;
typedef struct _TileList {
Tile* first;
Tile* last;
typedef struct _TileList
{
Tile *first;
Tile *last;
} TileList;
static unsigned long max_tile_size = TILE_WIDTH * TILE_HEIGHT * 4;
@ -222,7 +226,7 @@ tile_cache_flush_internal (Tile *tile)
/* untested -- ADM */
void
tile_cache_set_size (unsigned long cache_size)
tile_cache_set_size (gulong cache_size)
{
if (initialize)
tile_cache_init ();
@ -239,7 +243,7 @@ tile_cache_set_size (unsigned long cache_size)
static void
tile_cache_init ()
tile_cache_init (void)
{
if (initialize)
{
@ -253,7 +257,7 @@ tile_cache_init ()
#ifdef USE_PTHREADS
pthread_create (&preswap_thread, NULL, &tile_idle_thread, NULL);
#else
idle_swapper = gtk_timeout_add (250,
idle_swapper = gtk_timeout_add (IDLE_SWAPPER_TIMEOUT,
(GtkFunction) tile_idle_preswap,
(gpointer) 0);
#endif
@ -261,15 +265,16 @@ tile_cache_init ()
}
static gint
tile_cache_zorch_next ()
tile_cache_zorch_next (void)
{
Tile *tile;
/* fprintf(stderr, "cache zorch: %u/%u\n", cur_cache_size, cur_cache_dirty);*/
if (clean_list.first) tile = clean_list.first;
else if (dirty_list.first) tile = dirty_list.first;
else return FALSE;
if (clean_list.first)
tile = clean_list.first;
else if (dirty_list.first)
tile = dirty_list.first;
else
return FALSE;
CACHE_UNLOCK;
TILE_MUTEX_LOCK (tile);
@ -279,29 +284,34 @@ tile_cache_zorch_next ()
{
tile_swap_out (tile);
}
if (! tile->dirty) {
g_free (tile->data);
tile->data = NULL;
TILE_MUTEX_UNLOCK (tile);
return TRUE;
}
if (! tile->dirty)
{
g_free (tile->data);
tile->data = NULL;
TILE_MUTEX_UNLOCK (tile);
return TRUE;
}
/* unable to swap out tile for some reason */
TILE_MUTEX_UNLOCK (tile);
return FALSE;
}
#if USE_PTHREADS
static void *
tile_idle_thread (void *data)
static gpointer
tile_idle_thread (gpointer data)
{
Tile *tile;
Tile *tile;
TileList *list;
int count;
gint count;
fprintf (stderr, "starting tile preswapper\n");
g_printerr ("starting tile preswapper\n");
count = 0;
while (1)
while (TRUE)
{
CACHE_LOCK;
if (count > 5 || dirty_list.first == NULL)

View File

@ -18,19 +18,17 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include <glib.h>
#include "apptypes.h"
#include "tile.h"
#include "tile_pvt.h"
#include "tile_cache.h"
#include "tile_manager.h"
#include "tile_manager_pvt.h"
#include "tile_swap.h"
#include "tile_pvt.h" /* ick. */
static gint tile_manager_get_tile_num (TileManager *tm,
gint xpixel,
@ -301,8 +299,8 @@ tile_manager_invalidate_tiles (TileManager *tm,
col = toplevel_tile->tlink->tile_num % tm->ntile_cols;
row = toplevel_tile->tlink->tile_num / tm->ntile_cols;
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (double) tm->width;
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (double) tm->height;
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (gdouble) tm->width;
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (gdouble) tm->height;
if (tm->tiles)
{

View File

@ -2,6 +2,8 @@
#define __TILE_PVT_H__
#include "config.h"
#ifdef USE_PTHREADS
#include <pthread.h>
#endif
@ -9,20 +11,18 @@
#include <sys/types.h>
#include <glib.h>
#include "config.h"
#include "tile.h"
typedef struct _TileLink TileLink;
struct _TileLink
{
TileLink *next;
int tile_num; /* the number of this tile within the drawable */
void *tm; /* A pointer to the tile manager for this tile.
* We need this in order to call the tile managers
* validate proc whenever the tile is referenced yet
* invalid.
*/
TileLink *next;
gint tile_num; /* the number of this tile within the drawable */
TileManager *tm; /* A pointer to the tile manager for this tile.
* We need this in order to call the tile managers
* validate proc whenever the tile is referenced
* yet invalid.
*/
};
struct _Tile

View File

@ -18,11 +18,9 @@
#include "config.h"
#include <gtk/gtk.h>
#include <glib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -47,8 +45,9 @@
#include "apptypes.h"
#include "tile.h"
#include "tile_pvt.h"
#include "tile_swap.h"
#include "tile_pvt.h" /* ick. */
#define MAX_OPEN_SWAP_FILES 16
@ -59,96 +58,97 @@ typedef struct _AsyncSwapArgs AsyncSwapArgs;
struct _SwapFile
{
char *filename;
int swap_num;
SwapFunc swap_func;
gpointer user_data;
int fd;
gchar *filename;
gint swap_num;
SwapFunc swap_func;
gpointer user_data;
gint fd;
};
struct _DefSwapFile
{
GList *gaps;
long swap_file_end;
off_t cur_position;
glong swap_file_end;
off_t cur_position;
};
struct _Gap
{
long start;
long end;
glong start;
glong end;
};
struct _AsyncSwapArgs
{
DefSwapFile *def_swap_file;
int fd;
gint fd;
Tile *tile;
};
static void tile_swap_init (void);
static guint tile_swap_hash (int *key);
static gint tile_swap_compare (int *a,
int *b);
static void tile_swap_command (Tile *tile,
int command);
static void tile_swap_open (SwapFile *swap_file);
static void tile_swap_init (void);
static guint tile_swap_hash (gint *key);
static gint tile_swap_compare (gint *a,
gint *b);
static void tile_swap_command (Tile *tile,
gint command);
static void tile_swap_open (SwapFile *swap_file);
static int tile_swap_default (int fd,
Tile *tile,
int cmd,
gpointer user_data);
static void tile_swap_default_in (DefSwapFile *def_swap_file,
int fd,
Tile *tile);
static void tile_swap_default_in_async (DefSwapFile *def_swap_file,
int fd,
Tile *tile);
static void tile_swap_default_out (DefSwapFile *def_swap_file,
int fd,
Tile *tile);
static void tile_swap_default_delete (DefSwapFile *def_swap_file,
int fd,
Tile *tile);
static long tile_swap_find_offset (DefSwapFile *def_swap_file,
int fd,
int bytes);
static void tile_swap_resize (DefSwapFile *def_swap_file,
int fd,
long new_size);
static Gap* tile_swap_gap_new (long start,
long end);
static void tile_swap_gap_destroy (Gap *gap);
static gint tile_swap_default (gint fd,
Tile *tile,
gint cmd,
gpointer user_data);
static void tile_swap_default_in (DefSwapFile *def_swap_file,
gint fd,
Tile *tile);
static void tile_swap_default_in_async (DefSwapFile *def_swap_file,
gint fd,
Tile *tile);
static void tile_swap_default_out (DefSwapFile *def_swap_file,
gint fd,
Tile *tile);
static void tile_swap_default_delete (DefSwapFile *def_swap_file,
gint fd,
Tile *tile);
static glong tile_swap_find_offset (DefSwapFile *def_swap_file,
gint fd,
gint bytes);
static void tile_swap_resize (DefSwapFile *def_swap_file,
gint fd,
glong new_size);
static Gap * tile_swap_gap_new (glong start,
glong end);
static void tile_swap_gap_destroy (Gap *gap);
#ifdef USE_PTHREADS
static void* tile_swap_in_thread (void *);
static gpointer tile_swap_in_thread (gpointer);
#endif
static int initialize = TRUE;
static GHashTable *swap_files = NULL;
static GList *open_swap_files = NULL;
static int nopen_swap_files = 0;
static int next_swap_num = 1;
static long swap_file_grow = 16 * TILE_WIDTH * TILE_HEIGHT * 4;
static gboolean initialize = TRUE;
static GHashTable * swap_files = NULL;
static GList * open_swap_files = NULL;
static gint nopen_swap_files = 0;
static gint next_swap_num = 1;
static glong swap_file_grow = 16 * TILE_WIDTH * TILE_HEIGHT * 4;
#ifdef USE_PTHREADS
static pthread_mutex_t swapfile_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t swapfile_mutex = PTHREAD_MUTEX_INITIALIZER;
/* async_swapin_mutex protects only the list, not the tiles therein */
static pthread_t swapin_thread;
static pthread_mutex_t async_swapin_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t async_swapin_signal = PTHREAD_COND_INITIALIZER;
static GSList *async_swapin_tiles = NULL;
static GSList *async_swapin_tiles_end = NULL;
static pthread_t swapin_thread;
static pthread_mutex_t async_swapin_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t async_swapin_signal = PTHREAD_COND_INITIALIZER;
static GSList * async_swapin_tiles = NULL;
static GSList * async_swapin_tiles_end = NULL;
#endif
static gboolean seek_err_msg = TRUE, read_err_msg = TRUE, write_err_msg = TRUE;
static void
tile_swap_print_gaps (DefSwapFile *def_swap_file)
{
GList *gaps;
Gap *gap;
Gap *gap;
gaps = def_swap_file->gaps;
while (gaps)
@ -165,8 +165,8 @@ tile_swap_exit1 (gpointer key,
gpointer value,
gpointer data)
{
extern int tile_ref_count;
SwapFile *swap_file;
extern gint tile_ref_count;
SwapFile *swap_file;
DefSwapFile *def_swap_file;
if (tile_ref_count != 0)
@ -194,27 +194,26 @@ tile_swap_exit1 (gpointer key,
}
}
void
tile_swap_exit ()
tile_swap_exit (void)
{
#ifdef HINTS_SANITY
extern int tile_exist_peak;
fprintf(stderr,"Tile exist peak was %d Tile structs (%d bytes)",
tile_exist_peak, tile_exist_peak * sizeof(Tile));
g_printerr ("Tile exist peak was %d Tile structs (%d bytes)",
tile_exist_peak, tile_exist_peak * sizeof(Tile));
#endif
if (swap_files)
g_hash_table_foreach (swap_files, tile_swap_exit1, NULL);
}
int
tile_swap_add (char *filename,
gint
tile_swap_add (gchar *filename,
SwapFunc swap_func,
gpointer user_data)
{
SwapFile *swap_file;
SwapFile *swap_file;
DefSwapFile *def_swap_file;
#ifdef USE_PTHREADS
@ -253,7 +252,7 @@ tile_swap_add (char *filename,
}
void
tile_swap_remove (int swap_num)
tile_swap_remove (gint swap_num)
{
SwapFile *swap_file;
@ -315,13 +314,13 @@ tile_swap_delete (Tile *tile)
}
void
tile_swap_compress (int swap_num)
tile_swap_compress (gint swap_num)
{
tile_swap_command (NULL, SWAP_COMPRESS);
}
static void
tile_swap_init ()
tile_swap_init (void)
{
if (initialize)
@ -338,21 +337,21 @@ tile_swap_init ()
}
static guint
tile_swap_hash (int *key)
tile_swap_hash (gint *key)
{
return ((guint) *key);
return (guint) *key;
}
static gint
tile_swap_compare (int *a,
int *b)
tile_swap_compare (gint *a,
gint *b)
{
return (*a == *b);
}
static void
tile_swap_command (Tile *tile,
int command)
gint command)
{
SwapFile *swap_file;
#ifdef USE_PTHREADS
@ -377,11 +376,15 @@ tile_swap_command (Tile *tile,
if (swap_file->fd == -1)
goto out;
}
} while ((* swap_file->swap_func) (swap_file->fd, tile, command, swap_file->user_data));
}
while ((* swap_file->swap_func) (swap_file->fd,
tile, command, swap_file->user_data));
out:
#ifdef USE_PTHREADS
pthread_mutex_unlock(&swapfile_mutex);
#endif
return;
}
@ -427,9 +430,9 @@ tile_swap_open (SwapFile *swap_file)
*/
static int
tile_swap_default (int fd,
tile_swap_default (gint fd,
Tile *tile,
int cmd,
gint cmd,
gpointer user_data)
{
DefSwapFile *def_swap_file;
@ -460,7 +463,7 @@ tile_swap_default (int fd,
static void
tile_swap_default_in_async (DefSwapFile *def_swap_file,
int fd,
gint fd,
Tile *tile)
{
#ifdef NOTDEF /* USE_PTHREADS */
@ -506,12 +509,12 @@ tile_swap_default_in_async (DefSwapFile *def_swap_file,
*/
static void
tile_swap_default_in (DefSwapFile *def_swap_file,
int fd,
gint fd,
Tile *tile)
{
int bytes;
int err;
int nleft;
gint bytes;
gint err;
gint nleft;
off_t offset;
err = -1;
@ -541,14 +544,17 @@ tile_swap_default_in (DefSwapFile *def_swap_file,
nleft = bytes;
while (nleft > 0)
{
do {
err = read (fd, tile->data + bytes - nleft, nleft);
} while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
do
{
err = read (fd, tile->data + bytes - nleft, nleft);
}
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
if (err <= 0)
{
if (read_err_msg)
g_message ("unable to read tile data from disk: %d/%d ( %d ) bytes read", err, errno, nleft);
g_message ("unable to read tile data from disk: %s (%d/%d bytes read)",
g_strerror (errno), err, nleft);
read_err_msg = FALSE;
return;
}
@ -569,12 +575,11 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
int fd,
Tile *tile)
{
int bytes;
int rbytes;
int err;
int nleft;
gint bytes;
gint rbytes;
gint err;
gint nleft;
off_t offset;
off_t newpos;
bytes = TILE_WIDTH * TILE_HEIGHT * tile->bpp;
@ -592,7 +597,8 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
if (offset == -1)
{
if (seek_err_msg)
g_message ("unable to seek to tile location on disk: %d", errno);
g_message ("unable to seek to tile location on disk: %s",
g_strerror (errno));
seek_err_msg = FALSE;
return;
}
@ -606,7 +612,8 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
if (err <= 0)
{
if (write_err_msg)
g_message ("unable to write tile data to disk: %d ( %d ) bytes written", err, nleft);
g_message ("unable to write tile data to disk: %s (%d/%d bytes written)",
g_strerror (errno), err, nleft);
write_err_msg = FALSE;
return;
}
@ -627,15 +634,15 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
static void
tile_swap_default_delete (DefSwapFile *def_swap_file,
int fd,
gint fd,
Tile *tile)
{
GList *tmp;
GList *tmp2;
Gap *gap;
Gap *gap2;
long start;
long end;
Gap *gap;
Gap *gap2;
glong start;
glong end;
if (tile->swap_offset == -1)
return;
@ -660,7 +667,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
{
gap2->end = gap->end;
tile_swap_gap_destroy (gap);
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
def_swap_file->gaps =
g_list_remove_link (def_swap_file->gaps, tmp);
g_list_free (tmp);
}
}
@ -677,7 +685,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
{
gap2->start = gap->start;
tile_swap_gap_destroy (gap);
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
def_swap_file->gaps =
g_list_remove_link (def_swap_file->gaps, tmp);
g_list_free (tmp);
}
}
@ -731,26 +740,25 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
static void
tile_swap_resize (DefSwapFile *def_swap_file,
int fd,
long new_size)
gint fd,
glong new_size)
{
if (def_swap_file->swap_file_end > new_size)
{
ftruncate (fd, new_size);
/*fprintf(stderr, "TRUNCATED SWAP from %d to %d bytes.\n",
(int)def_swap_file->swap_file_end, (int) new_size);*/
}
def_swap_file->swap_file_end = new_size;
}
static long
tile_swap_find_offset (DefSwapFile *def_swap_file,
int fd,
int bytes)
gint fd,
gint bytes)
{
GList *tmp;
Gap *gap;
long offset;
Gap *gap;
glong offset;
tmp = def_swap_file->gaps;
while (tmp)
@ -765,7 +773,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
if (gap->start == gap->end)
{
tile_swap_gap_destroy (gap);
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
def_swap_file->gaps =
g_list_remove_link (def_swap_file->gaps, tmp);
g_list_free (tmp);
}
@ -777,7 +786,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
offset = def_swap_file->swap_file_end;
tile_swap_resize (def_swap_file, fd, def_swap_file->swap_file_end + swap_file_grow);
tile_swap_resize (def_swap_file, fd,
def_swap_file->swap_file_end + swap_file_grow);
if ((offset + bytes) < (def_swap_file->swap_file_end))
{
@ -788,9 +798,9 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
return offset;
}
static Gap*
tile_swap_gap_new (long start,
long end)
static Gap *
tile_swap_gap_new (glong start,
glong end)
{
Gap *gap;
@ -822,12 +832,12 @@ tile_swap_gap_destroy (Gap *gap)
static void
tile_swap_in_attempt (DefSwapFile *def_swap_file,
int fd,
gint fd,
Tile *tile)
{
int bytes;
int err;
int nleft;
gint bytes;
gint err;
gint nleft;
off_t offset;
err = -1;
@ -854,9 +864,11 @@ tile_swap_in_attempt (DefSwapFile *def_swap_file,
nleft = bytes;
while (nleft > 0)
{
do {
err = read (fd, tile->data + bytes - nleft, nleft);
} while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
do
{
err = read (fd, tile->data + bytes - nleft, nleft);
}
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
if (err <= 0)
{
@ -873,13 +885,13 @@ out:
TILE_MUTEX_UNLOCK (tile);
}
static void *
tile_swap_in_thread (void *data)
static gpointer
tile_swap_in_thread (gpointer data)
{
AsyncSwapArgs *args;
GSList *free_item;
GSList *free_item;
while (1)
while (TRUE)
{
pthread_mutex_lock (&async_swapin_mutex);
@ -892,6 +904,7 @@ tile_swap_in_thread (void *data)
free_item = async_swapin_tiles;
async_swapin_tiles = async_swapin_tiles->next;
g_slist_free_1(free_item);
if (!async_swapin_tiles)
async_swapin_tiles_end = NULL;

View File

@ -30,7 +30,7 @@ typedef enum
} SwapCommand;
typedef gint (*SwapFunc) (gint fd,
Tile *tile,
Tile *tile,
gint cmd,
gpointer user_data);

View File

@ -18,11 +18,9 @@
#include "config.h"
#include <stdio.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <apptypes.h>
#include "apptypes.h"
#include "tile.h"
#include "tile_pvt.h"
@ -168,7 +166,6 @@ tile_lock (Tile *tile)
}
}
void
tile_release (Tile *tile, int dirty)
{
@ -280,7 +277,6 @@ tile_destroy (Tile *tile)
#endif
}
gint
tile_size (Tile *tile)
{

View File

@ -33,7 +33,6 @@
#include "pixel_processor.h"
#include "pixel_region.h"
#include "tile_manager.h"
#include "tile_pvt.h"
#include "tile.h"
#include "libgimp/gimpmath.h"
@ -161,7 +160,7 @@ update_tile_rowhints (Tile *tile,
tile_sanitize_rowhints (tile);
bpp = tile_bpp (tile);
ewidth = tile->ewidth;
ewidth = tile_ewidth (tile);
if (bpp == 1 || bpp == 3)
{
@ -3458,10 +3457,10 @@ copy_region (PixelRegion *src,
src->curtile && dest->curtile &&
src->offx == 0 && dest->offx == 0 &&
src->offy == 0 && dest->offy == 0 &&
src->w == (src->curtile->ewidth) &&
dest->w == (dest->curtile->ewidth) &&
src->h == tile_eheight(src->curtile) &&
dest->h == tile_eheight(dest->curtile))
src->w == tile_ewidth (src->curtile) &&
dest->w == tile_ewidth (dest->curtile) &&
src->h == tile_eheight (src->curtile) &&
dest->h == tile_eheight (dest->curtile))
{
#ifdef COWSHOW
fputc('!',stderr);
@ -4639,12 +4638,15 @@ shapeburst_region (PixelRegion *srcPR,
while (y >= end)
{
tile = tile_manager_get_tile (srcPR->tiles, x, y, TRUE, FALSE);
tile_data = tile_data_pointer (tile, x%TILE_WIDTH, y%TILE_HEIGHT);
tile = tile_manager_get_tile (srcPR->tiles,
x, y, TRUE, FALSE);
tile_data = tile_data_pointer (tile,
x % TILE_WIDTH,
y % TILE_HEIGHT);
boundary = MIN ((y % TILE_HEIGHT),
(tile->ewidth - (x % TILE_WIDTH) - 1));
(tile_ewidth (tile) - (x % TILE_WIDTH) - 1));
boundary = MIN (boundary, (y - end)) + 1;
inc = 1 - (tile->ewidth);
inc = 1 - tile_ewidth (tile);
while (boundary--)
{

View File

@ -33,7 +33,6 @@
#include "pixel_processor.h"
#include "pixel_region.h"
#include "tile_manager.h"
#include "tile_pvt.h"
#include "tile.h"
#include "libgimp/gimpmath.h"
@ -161,7 +160,7 @@ update_tile_rowhints (Tile *tile,
tile_sanitize_rowhints (tile);
bpp = tile_bpp (tile);
ewidth = tile->ewidth;
ewidth = tile_ewidth (tile);
if (bpp == 1 || bpp == 3)
{
@ -3458,10 +3457,10 @@ copy_region (PixelRegion *src,
src->curtile && dest->curtile &&
src->offx == 0 && dest->offx == 0 &&
src->offy == 0 && dest->offy == 0 &&
src->w == (src->curtile->ewidth) &&
dest->w == (dest->curtile->ewidth) &&
src->h == tile_eheight(src->curtile) &&
dest->h == tile_eheight(dest->curtile))
src->w == tile_ewidth (src->curtile) &&
dest->w == tile_ewidth (dest->curtile) &&
src->h == tile_eheight (src->curtile) &&
dest->h == tile_eheight (dest->curtile))
{
#ifdef COWSHOW
fputc('!',stderr);
@ -4639,12 +4638,15 @@ shapeburst_region (PixelRegion *srcPR,
while (y >= end)
{
tile = tile_manager_get_tile (srcPR->tiles, x, y, TRUE, FALSE);
tile_data = tile_data_pointer (tile, x%TILE_WIDTH, y%TILE_HEIGHT);
tile = tile_manager_get_tile (srcPR->tiles,
x, y, TRUE, FALSE);
tile_data = tile_data_pointer (tile,
x % TILE_WIDTH,
y % TILE_HEIGHT);
boundary = MIN ((y % TILE_HEIGHT),
(tile->ewidth - (x % TILE_WIDTH) - 1));
(tile_ewidth (tile) - (x % TILE_WIDTH) - 1));
boundary = MIN (boundary, (y - end)) + 1;
inc = 1 - (tile->ewidth);
inc = 1 - tile_ewidth (tile);
while (boundary--)
{

View File

@ -20,10 +20,6 @@
#include "config.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef ENABLE_MP
#include <pthread.h>
#define IF_THREAD(statement) statement
@ -31,9 +27,9 @@
#define IF_THREAD(statement)
#endif /* ENABLE_MP */
#include <gtk/gtk.h>
#include <glib.h>
#include <apptypes.h>
#include "apptypes.h"
#include "pixel_processor.h"
#include "pixel_region.h"
@ -75,7 +71,7 @@ struct _PixelProcessor
IF_THREAD(
static void *
do_parallel_regions (PixelProcessor *p_s)
do_parallel_regions (PixelProcessor *p_s)
{
PixelRegion tr[4];
int ntiles = 0;
@ -161,7 +157,7 @@ do_parallel_regions (PixelProcessor *p_s)
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
p_s->nthreads--;
/* fprintf(stderr, "processed %d tiles\n", ntiles); */
pthread_mutex_unlock(&p_s->mutex);
return NULL;
@ -176,30 +172,33 @@ do_parallel_regions (PixelProcessor *p_s)
* configured --with-mp
*/
static void *
do_parallel_regions_single(PixelProcessor *p_s)
static gpointer
do_parallel_regions_single (PixelProcessor *p_s)
{
int cont = 1;
gint cont = 1;
do
{
switch(p_s->n_regions)
switch (p_s->n_regions)
{
case 1:
((p1_func)p_s->f)(p_s->data,
p_s->r[0]);
break;
case 2:
((p2_func)p_s->f)(p_s->data,
p_s->r[0],
p_s->r[1]);
break;
case 3:
((p3_func)p_s->f)(p_s->data,
p_s->r[0],
p_s->r[1],
p_s->r[2]);
break;
case 4:
((p4_func)p_s->f)(p_s->data,
p_s->r[0],
@ -207,180 +206,207 @@ do_parallel_regions_single(PixelProcessor *p_s)
p_s->r[2],
p_s->r[3]);
break;
default:
g_message("do_parallel_regions_single: Bad number of regions %d\n",
p_s->n_regions);
}
if (p_s->progress_report_func)
if (!p_s->progress_report_func(p_s->progress_report_data,
p_s->r[0]->x, p_s->r[0]->y,
p_s->r[0]->w, p_s->r[0]->h))
if (!p_s->progress_report_func (p_s->progress_report_data,
p_s->r[0]->x, p_s->r[0]->y,
p_s->r[0]->w, p_s->r[0]->h))
cont = 0;
} while (cont && p_s->PRI &&
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
}
while (cont && p_s->PRI &&
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
return NULL;
}
#define MAX_THREADS 30
static void
pixel_regions_do_parallel(PixelProcessor *p_s)
pixel_regions_do_parallel (PixelProcessor *p_s)
{
IF_THREAD(
int nthreads;
nthreads = MIN(num_processors, MAX_THREADS);
IF_THREAD(
gint nthreads;
nthreads = MIN (num_processors, MAX_THREADS);
/* make sure we have at least one tile per thread */
nthreads = MIN(nthreads,
(p_s->PRI->region_width * p_s->PRI->region_height)
/(TILE_WIDTH*TILE_HEIGHT));
/* make sure we have at least one tile per thread */
nthreads = MIN (nthreads,
(p_s->PRI->region_width * p_s->PRI->region_height)
/ (TILE_WIDTH * TILE_HEIGHT));
if (nthreads > 1)
if (nthreads > 1)
{
int i;
gint i;
pthread_t threads[MAX_THREADS];
pthread_attr_t pthread_attr;
pthread_attr_init (&pthread_attr);
for (i = 0; i < nthreads; i++)
{
pthread_create (&threads[i], &pthread_attr,
(void *(*)(void *)) do_parallel_regions,
p_s);
}
{
pthread_create (&threads[i], &pthread_attr,
(void *(*)(void *)) do_parallel_regions,
p_s);
}
for (i = 0; i < nthreads; i++)
{
int ret;
if ((ret = pthread_join(threads[i], NULL)))
{
fprintf(stderr, "pixel_regions_do_parallel:: pthread_join returned: %d\n", ret);
}
}
{
gint ret;
if ((ret = pthread_join(threads[i], NULL)))
{
g_printerr ("pixel_regions_do_parallel:: pthread_join returned: %d\n", ret);
}
}
if (p_s->nthreads != 0)
fprintf(stderr, "pixel_regions_do_prarallel: we lost a thread\n");
g_printerr ("pixel_regions_do_prarallel: we lost a thread\n");
}
else
)
do_parallel_regions_single(p_s);
else
)
do_parallel_regions_single (p_s);
}
static PixelProcessor *
pixel_regions_real_process_parallel(p_func f, void *data,
ProgressReportFunc report_func,
void *report_data,
int num_regions, va_list ap)
pixel_regions_real_process_parallel (p_func f,
gpointer data,
ProgressReportFunc report_func,
gpointer report_data,
gint num_regions,
va_list ap)
{
int i;
gint i;
PixelProcessor *p_s;
p_s = g_new(PixelProcessor, 1);
p_s = g_new (PixelProcessor, 1);
for (i = 0; i < num_regions; i++)
p_s->r[i] = va_arg (ap, PixelRegion *);
switch(num_regions)
{
case 1:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
p_s->r[0]);
break;
case 2:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
p_s->r[0],
p_s->r[1]);
{
case 1:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
p_s->r[0]);
break;
case 2:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
p_s->r[0],
p_s->r[1]);
break;
case 3:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
p_s->r[0],
p_s->r[1],
p_s->r[2]);
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
p_s->r[0],
p_s->r[1],
p_s->r[2]);
break;
case 4:
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
p_s->r[0],
p_s->r[1],
p_s->r[2],
p_s->r[3]);
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
p_s->r[0],
p_s->r[1],
p_s->r[2],
p_s->r[3]);
break;
default:
g_message("pixel_regions_real_process_parallel: Bad number of regions %d\n",
p_s->n_regions);
g_message ("pixel_regions_real_process_parallel: Bad number of regions %d\n",
p_s->n_regions);
}
if (!p_s->PRI)
{
pixel_processor_free(p_s);
return NULL;
}
{
pixel_processor_free (p_s);
return NULL;
}
/* Why would we wan't to set dirty_tiles to 0 here? */
/* IF_THREAD(p_s->PRI->dirty_tiles = 0;) */
p_s->f = f;
p_s->data = data;
p_s->n_regions = num_regions;
IF_THREAD(pthread_mutex_init(&(p_s->mutex), NULL);)
IF_THREAD (pthread_mutex_init(&(p_s->mutex), NULL);)
p_s->nthreads = 0;
p_s->progress_report_data = report_data;
p_s->progress_report_func = report_func;
pixel_regions_do_parallel(p_s);
pixel_regions_do_parallel (p_s);
if (p_s->PRI)
return p_s;
pixel_processor_free (p_s);
return NULL;
}
void
pixel_regions_process_parallel(p_func f, void *data, int num_regions, ...)
pixel_regions_process_parallel (p_func f,
gpointer data,
gint num_regions,
...)
{
va_list va;
va_start (va, num_regions);
pixel_regions_real_process_parallel(f, data, NULL, NULL, num_regions, va);
pixel_regions_real_process_parallel (f, data, NULL, NULL, num_regions, va);
va_end (va);
}
PixelProcessor *
pixel_regions_process_parallel_progress(p_func f, void *data,
ProgressReportFunc progress_func,
void *progress_data, int num_regions,
...)
pixel_regions_process_parallel_progress (p_func f,
gpointer data,
ProgressReportFunc progress_func,
gpointer progress_data,
gint num_regions,
...)
{
PixelProcessor *ret;
va_list va;
va_start (va, num_regions);
va_list va;
ret = pixel_regions_real_process_parallel(f, data,
progress_func, progress_data,
num_regions, va);
va_start (va, num_regions);
ret = pixel_regions_real_process_parallel (f, data,
progress_func, progress_data,
num_regions, va);
va_end (va);
return ret;
}
void
pixel_processor_stop(PixelProcessor *pp)
pixel_processor_stop (PixelProcessor *pp)
{
if (!pp)
return;
if (pp->PRI)
{
pixel_regions_process_stop (pp->PRI);
pp->PRI = NULL;
}
pixel_processor_free(pp);
{
pixel_regions_process_stop (pp->PRI);
pp->PRI = NULL;
}
pixel_processor_free (pp);
}
PixelProcessor *
pixel_processor_cont(PixelProcessor *pp)
pixel_processor_cont (PixelProcessor *pp)
{
pixel_regions_do_parallel(pp);
pixel_regions_do_parallel (pp);
if (pp->PRI)
return pp;
pixel_processor_free (pp);
return NULL;
}
@ -388,7 +414,7 @@ void
pixel_processor_free (PixelProcessor *pp)
{
if (pp->PRI)
pixel_processor_stop(pp);
pixel_processor_stop (pp);
else
g_free(pp);
}

View File

@ -18,11 +18,9 @@
#include "config.h"
#include <stdio.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <apptypes.h>
#include "apptypes.h"
#include "tile.h"
#include "tile_pvt.h"
@ -168,7 +166,6 @@ tile_lock (Tile *tile)
}
}
void
tile_release (Tile *tile, int dirty)
{
@ -280,7 +277,6 @@ tile_destroy (Tile *tile)
#endif
}
gint
tile_size (Tile *tile)
{

View File

@ -18,7 +18,6 @@
#include "config.h"
#include <stdio.h>
#ifdef USE_PTHREADS
#include <pthread.h>
#endif
@ -37,23 +36,28 @@
/* This is the percentage of the maximum cache size that should be cleared
* from the cache when an eviction is necessary
*/
#define FREE_QUANTUM 0.1
#define FREE_QUANTUM 0.1
static void tile_cache_init (void);
static gint tile_cache_zorch_next (void);
static void tile_cache_flush_internal (Tile *tile);
#define IDLE_SWAPPER_TIMEOUT 250
static void tile_cache_init (void);
static gint tile_cache_zorch_next (void);
static void tile_cache_flush_internal (Tile *tile);
#ifdef USE_PTHREADS
static void* tile_idle_thread (void *);
static gpointer tile_idle_thread (gpointer data);
#else
static gint tile_idle_preswap (gpointer);
static gint tile_idle_preswap (gpointer data);
#endif
static int initialize = TRUE;
typedef struct _TileList {
Tile* first;
Tile* last;
typedef struct _TileList
{
Tile *first;
Tile *last;
} TileList;
static unsigned long max_tile_size = TILE_WIDTH * TILE_HEIGHT * 4;
@ -222,7 +226,7 @@ tile_cache_flush_internal (Tile *tile)
/* untested -- ADM */
void
tile_cache_set_size (unsigned long cache_size)
tile_cache_set_size (gulong cache_size)
{
if (initialize)
tile_cache_init ();
@ -239,7 +243,7 @@ tile_cache_set_size (unsigned long cache_size)
static void
tile_cache_init ()
tile_cache_init (void)
{
if (initialize)
{
@ -253,7 +257,7 @@ tile_cache_init ()
#ifdef USE_PTHREADS
pthread_create (&preswap_thread, NULL, &tile_idle_thread, NULL);
#else
idle_swapper = gtk_timeout_add (250,
idle_swapper = gtk_timeout_add (IDLE_SWAPPER_TIMEOUT,
(GtkFunction) tile_idle_preswap,
(gpointer) 0);
#endif
@ -261,15 +265,16 @@ tile_cache_init ()
}
static gint
tile_cache_zorch_next ()
tile_cache_zorch_next (void)
{
Tile *tile;
/* fprintf(stderr, "cache zorch: %u/%u\n", cur_cache_size, cur_cache_dirty);*/
if (clean_list.first) tile = clean_list.first;
else if (dirty_list.first) tile = dirty_list.first;
else return FALSE;
if (clean_list.first)
tile = clean_list.first;
else if (dirty_list.first)
tile = dirty_list.first;
else
return FALSE;
CACHE_UNLOCK;
TILE_MUTEX_LOCK (tile);
@ -279,29 +284,34 @@ tile_cache_zorch_next ()
{
tile_swap_out (tile);
}
if (! tile->dirty) {
g_free (tile->data);
tile->data = NULL;
TILE_MUTEX_UNLOCK (tile);
return TRUE;
}
if (! tile->dirty)
{
g_free (tile->data);
tile->data = NULL;
TILE_MUTEX_UNLOCK (tile);
return TRUE;
}
/* unable to swap out tile for some reason */
TILE_MUTEX_UNLOCK (tile);
return FALSE;
}
#if USE_PTHREADS
static void *
tile_idle_thread (void *data)
static gpointer
tile_idle_thread (gpointer data)
{
Tile *tile;
Tile *tile;
TileList *list;
int count;
gint count;
fprintf (stderr, "starting tile preswapper\n");
g_printerr ("starting tile preswapper\n");
count = 0;
while (1)
while (TRUE)
{
CACHE_LOCK;
if (count > 5 || dirty_list.first == NULL)

View File

@ -18,19 +18,17 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include <glib.h>
#include "apptypes.h"
#include "tile.h"
#include "tile_pvt.h"
#include "tile_cache.h"
#include "tile_manager.h"
#include "tile_manager_pvt.h"
#include "tile_swap.h"
#include "tile_pvt.h" /* ick. */
static gint tile_manager_get_tile_num (TileManager *tm,
gint xpixel,
@ -301,8 +299,8 @@ tile_manager_invalidate_tiles (TileManager *tm,
col = toplevel_tile->tlink->tile_num % tm->ntile_cols;
row = toplevel_tile->tlink->tile_num / tm->ntile_cols;
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (double) tm->width;
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (double) tm->height;
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (gdouble) tm->width;
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (gdouble) tm->height;
if (tm->tiles)
{

View File

@ -2,6 +2,8 @@
#define __TILE_PVT_H__
#include "config.h"
#ifdef USE_PTHREADS
#include <pthread.h>
#endif
@ -9,20 +11,18 @@
#include <sys/types.h>
#include <glib.h>
#include "config.h"
#include "tile.h"
typedef struct _TileLink TileLink;
struct _TileLink
{
TileLink *next;
int tile_num; /* the number of this tile within the drawable */
void *tm; /* A pointer to the tile manager for this tile.
* We need this in order to call the tile managers
* validate proc whenever the tile is referenced yet
* invalid.
*/
TileLink *next;
gint tile_num; /* the number of this tile within the drawable */
TileManager *tm; /* A pointer to the tile manager for this tile.
* We need this in order to call the tile managers
* validate proc whenever the tile is referenced
* yet invalid.
*/
};
struct _Tile

View File

@ -18,11 +18,9 @@
#include "config.h"
#include <gtk/gtk.h>
#include <glib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -47,8 +45,9 @@
#include "apptypes.h"
#include "tile.h"
#include "tile_pvt.h"
#include "tile_swap.h"
#include "tile_pvt.h" /* ick. */
#define MAX_OPEN_SWAP_FILES 16
@ -59,96 +58,97 @@ typedef struct _AsyncSwapArgs AsyncSwapArgs;
struct _SwapFile
{
char *filename;
int swap_num;
SwapFunc swap_func;
gpointer user_data;
int fd;
gchar *filename;
gint swap_num;
SwapFunc swap_func;
gpointer user_data;
gint fd;
};
struct _DefSwapFile
{
GList *gaps;
long swap_file_end;
off_t cur_position;
glong swap_file_end;
off_t cur_position;
};
struct _Gap
{
long start;
long end;
glong start;
glong end;
};
struct _AsyncSwapArgs
{
DefSwapFile *def_swap_file;
int fd;
gint fd;
Tile *tile;
};
static void tile_swap_init (void);
static guint tile_swap_hash (int *key);
static gint tile_swap_compare (int *a,
int *b);
static void tile_swap_command (Tile *tile,
int command);
static void tile_swap_open (SwapFile *swap_file);
static void tile_swap_init (void);
static guint tile_swap_hash (gint *key);
static gint tile_swap_compare (gint *a,
gint *b);
static void tile_swap_command (Tile *tile,
gint command);
static void tile_swap_open (SwapFile *swap_file);
static int tile_swap_default (int fd,
Tile *tile,
int cmd,
gpointer user_data);
static void tile_swap_default_in (DefSwapFile *def_swap_file,
int fd,
Tile *tile);
static void tile_swap_default_in_async (DefSwapFile *def_swap_file,
int fd,
Tile *tile);
static void tile_swap_default_out (DefSwapFile *def_swap_file,
int fd,
Tile *tile);
static void tile_swap_default_delete (DefSwapFile *def_swap_file,
int fd,
Tile *tile);
static long tile_swap_find_offset (DefSwapFile *def_swap_file,
int fd,
int bytes);
static void tile_swap_resize (DefSwapFile *def_swap_file,
int fd,
long new_size);
static Gap* tile_swap_gap_new (long start,
long end);
static void tile_swap_gap_destroy (Gap *gap);
static gint tile_swap_default (gint fd,
Tile *tile,
gint cmd,
gpointer user_data);
static void tile_swap_default_in (DefSwapFile *def_swap_file,
gint fd,
Tile *tile);
static void tile_swap_default_in_async (DefSwapFile *def_swap_file,
gint fd,
Tile *tile);
static void tile_swap_default_out (DefSwapFile *def_swap_file,
gint fd,
Tile *tile);
static void tile_swap_default_delete (DefSwapFile *def_swap_file,
gint fd,
Tile *tile);
static glong tile_swap_find_offset (DefSwapFile *def_swap_file,
gint fd,
gint bytes);
static void tile_swap_resize (DefSwapFile *def_swap_file,
gint fd,
glong new_size);
static Gap * tile_swap_gap_new (glong start,
glong end);
static void tile_swap_gap_destroy (Gap *gap);
#ifdef USE_PTHREADS
static void* tile_swap_in_thread (void *);
static gpointer tile_swap_in_thread (gpointer);
#endif
static int initialize = TRUE;
static GHashTable *swap_files = NULL;
static GList *open_swap_files = NULL;
static int nopen_swap_files = 0;
static int next_swap_num = 1;
static long swap_file_grow = 16 * TILE_WIDTH * TILE_HEIGHT * 4;
static gboolean initialize = TRUE;
static GHashTable * swap_files = NULL;
static GList * open_swap_files = NULL;
static gint nopen_swap_files = 0;
static gint next_swap_num = 1;
static glong swap_file_grow = 16 * TILE_WIDTH * TILE_HEIGHT * 4;
#ifdef USE_PTHREADS
static pthread_mutex_t swapfile_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t swapfile_mutex = PTHREAD_MUTEX_INITIALIZER;
/* async_swapin_mutex protects only the list, not the tiles therein */
static pthread_t swapin_thread;
static pthread_mutex_t async_swapin_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t async_swapin_signal = PTHREAD_COND_INITIALIZER;
static GSList *async_swapin_tiles = NULL;
static GSList *async_swapin_tiles_end = NULL;
static pthread_t swapin_thread;
static pthread_mutex_t async_swapin_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t async_swapin_signal = PTHREAD_COND_INITIALIZER;
static GSList * async_swapin_tiles = NULL;
static GSList * async_swapin_tiles_end = NULL;
#endif
static gboolean seek_err_msg = TRUE, read_err_msg = TRUE, write_err_msg = TRUE;
static void
tile_swap_print_gaps (DefSwapFile *def_swap_file)
{
GList *gaps;
Gap *gap;
Gap *gap;
gaps = def_swap_file->gaps;
while (gaps)
@ -165,8 +165,8 @@ tile_swap_exit1 (gpointer key,
gpointer value,
gpointer data)
{
extern int tile_ref_count;
SwapFile *swap_file;
extern gint tile_ref_count;
SwapFile *swap_file;
DefSwapFile *def_swap_file;
if (tile_ref_count != 0)
@ -194,27 +194,26 @@ tile_swap_exit1 (gpointer key,
}
}
void
tile_swap_exit ()
tile_swap_exit (void)
{
#ifdef HINTS_SANITY
extern int tile_exist_peak;
fprintf(stderr,"Tile exist peak was %d Tile structs (%d bytes)",
tile_exist_peak, tile_exist_peak * sizeof(Tile));
g_printerr ("Tile exist peak was %d Tile structs (%d bytes)",
tile_exist_peak, tile_exist_peak * sizeof(Tile));
#endif
if (swap_files)
g_hash_table_foreach (swap_files, tile_swap_exit1, NULL);
}
int
tile_swap_add (char *filename,
gint
tile_swap_add (gchar *filename,
SwapFunc swap_func,
gpointer user_data)
{
SwapFile *swap_file;
SwapFile *swap_file;
DefSwapFile *def_swap_file;
#ifdef USE_PTHREADS
@ -253,7 +252,7 @@ tile_swap_add (char *filename,
}
void
tile_swap_remove (int swap_num)
tile_swap_remove (gint swap_num)
{
SwapFile *swap_file;
@ -315,13 +314,13 @@ tile_swap_delete (Tile *tile)
}
void
tile_swap_compress (int swap_num)
tile_swap_compress (gint swap_num)
{
tile_swap_command (NULL, SWAP_COMPRESS);
}
static void
tile_swap_init ()
tile_swap_init (void)
{
if (initialize)
@ -338,21 +337,21 @@ tile_swap_init ()
}
static guint
tile_swap_hash (int *key)
tile_swap_hash (gint *key)
{
return ((guint) *key);
return (guint) *key;
}
static gint
tile_swap_compare (int *a,
int *b)
tile_swap_compare (gint *a,
gint *b)
{
return (*a == *b);
}
static void
tile_swap_command (Tile *tile,
int command)
gint command)
{
SwapFile *swap_file;
#ifdef USE_PTHREADS
@ -377,11 +376,15 @@ tile_swap_command (Tile *tile,
if (swap_file->fd == -1)
goto out;
}
} while ((* swap_file->swap_func) (swap_file->fd, tile, command, swap_file->user_data));
}
while ((* swap_file->swap_func) (swap_file->fd,
tile, command, swap_file->user_data));
out:
#ifdef USE_PTHREADS
pthread_mutex_unlock(&swapfile_mutex);
#endif
return;
}
@ -427,9 +430,9 @@ tile_swap_open (SwapFile *swap_file)
*/
static int
tile_swap_default (int fd,
tile_swap_default (gint fd,
Tile *tile,
int cmd,
gint cmd,
gpointer user_data)
{
DefSwapFile *def_swap_file;
@ -460,7 +463,7 @@ tile_swap_default (int fd,
static void
tile_swap_default_in_async (DefSwapFile *def_swap_file,
int fd,
gint fd,
Tile *tile)
{
#ifdef NOTDEF /* USE_PTHREADS */
@ -506,12 +509,12 @@ tile_swap_default_in_async (DefSwapFile *def_swap_file,
*/
static void
tile_swap_default_in (DefSwapFile *def_swap_file,
int fd,
gint fd,
Tile *tile)
{
int bytes;
int err;
int nleft;
gint bytes;
gint err;
gint nleft;
off_t offset;
err = -1;
@ -541,14 +544,17 @@ tile_swap_default_in (DefSwapFile *def_swap_file,
nleft = bytes;
while (nleft > 0)
{
do {
err = read (fd, tile->data + bytes - nleft, nleft);
} while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
do
{
err = read (fd, tile->data + bytes - nleft, nleft);
}
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
if (err <= 0)
{
if (read_err_msg)
g_message ("unable to read tile data from disk: %d/%d ( %d ) bytes read", err, errno, nleft);
g_message ("unable to read tile data from disk: %s (%d/%d bytes read)",
g_strerror (errno), err, nleft);
read_err_msg = FALSE;
return;
}
@ -569,12 +575,11 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
int fd,
Tile *tile)
{
int bytes;
int rbytes;
int err;
int nleft;
gint bytes;
gint rbytes;
gint err;
gint nleft;
off_t offset;
off_t newpos;
bytes = TILE_WIDTH * TILE_HEIGHT * tile->bpp;
@ -592,7 +597,8 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
if (offset == -1)
{
if (seek_err_msg)
g_message ("unable to seek to tile location on disk: %d", errno);
g_message ("unable to seek to tile location on disk: %s",
g_strerror (errno));
seek_err_msg = FALSE;
return;
}
@ -606,7 +612,8 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
if (err <= 0)
{
if (write_err_msg)
g_message ("unable to write tile data to disk: %d ( %d ) bytes written", err, nleft);
g_message ("unable to write tile data to disk: %s (%d/%d bytes written)",
g_strerror (errno), err, nleft);
write_err_msg = FALSE;
return;
}
@ -627,15 +634,15 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
static void
tile_swap_default_delete (DefSwapFile *def_swap_file,
int fd,
gint fd,
Tile *tile)
{
GList *tmp;
GList *tmp2;
Gap *gap;
Gap *gap2;
long start;
long end;
Gap *gap;
Gap *gap2;
glong start;
glong end;
if (tile->swap_offset == -1)
return;
@ -660,7 +667,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
{
gap2->end = gap->end;
tile_swap_gap_destroy (gap);
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
def_swap_file->gaps =
g_list_remove_link (def_swap_file->gaps, tmp);
g_list_free (tmp);
}
}
@ -677,7 +685,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
{
gap2->start = gap->start;
tile_swap_gap_destroy (gap);
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
def_swap_file->gaps =
g_list_remove_link (def_swap_file->gaps, tmp);
g_list_free (tmp);
}
}
@ -731,26 +740,25 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
static void
tile_swap_resize (DefSwapFile *def_swap_file,
int fd,
long new_size)
gint fd,
glong new_size)
{
if (def_swap_file->swap_file_end > new_size)
{
ftruncate (fd, new_size);
/*fprintf(stderr, "TRUNCATED SWAP from %d to %d bytes.\n",
(int)def_swap_file->swap_file_end, (int) new_size);*/
}
def_swap_file->swap_file_end = new_size;
}
static long
tile_swap_find_offset (DefSwapFile *def_swap_file,
int fd,
int bytes)
gint fd,
gint bytes)
{
GList *tmp;
Gap *gap;
long offset;
Gap *gap;
glong offset;
tmp = def_swap_file->gaps;
while (tmp)
@ -765,7 +773,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
if (gap->start == gap->end)
{
tile_swap_gap_destroy (gap);
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
def_swap_file->gaps =
g_list_remove_link (def_swap_file->gaps, tmp);
g_list_free (tmp);
}
@ -777,7 +786,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
offset = def_swap_file->swap_file_end;
tile_swap_resize (def_swap_file, fd, def_swap_file->swap_file_end + swap_file_grow);
tile_swap_resize (def_swap_file, fd,
def_swap_file->swap_file_end + swap_file_grow);
if ((offset + bytes) < (def_swap_file->swap_file_end))
{
@ -788,9 +798,9 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
return offset;
}
static Gap*
tile_swap_gap_new (long start,
long end)
static Gap *
tile_swap_gap_new (glong start,
glong end)
{
Gap *gap;
@ -822,12 +832,12 @@ tile_swap_gap_destroy (Gap *gap)
static void
tile_swap_in_attempt (DefSwapFile *def_swap_file,
int fd,
gint fd,
Tile *tile)
{
int bytes;
int err;
int nleft;
gint bytes;
gint err;
gint nleft;
off_t offset;
err = -1;
@ -854,9 +864,11 @@ tile_swap_in_attempt (DefSwapFile *def_swap_file,
nleft = bytes;
while (nleft > 0)
{
do {
err = read (fd, tile->data + bytes - nleft, nleft);
} while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
do
{
err = read (fd, tile->data + bytes - nleft, nleft);
}
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
if (err <= 0)
{
@ -873,13 +885,13 @@ out:
TILE_MUTEX_UNLOCK (tile);
}
static void *
tile_swap_in_thread (void *data)
static gpointer
tile_swap_in_thread (gpointer data)
{
AsyncSwapArgs *args;
GSList *free_item;
GSList *free_item;
while (1)
while (TRUE)
{
pthread_mutex_lock (&async_swapin_mutex);
@ -892,6 +904,7 @@ tile_swap_in_thread (void *data)
free_item = async_swapin_tiles;
async_swapin_tiles = async_swapin_tiles->next;
g_slist_free_1(free_item);
if (!async_swapin_tiles)
async_swapin_tiles_end = NULL;

View File

@ -30,7 +30,7 @@ typedef enum
} SwapCommand;
typedef gint (*SwapFunc) (gint fd,
Tile *tile,
Tile *tile,
gint cmd,
gpointer user_data);