Пример #1
0
static void
test_atomic_flag(void)
{
	pg_atomic_flag flag;

	pg_atomic_init_flag(&flag);

	if (!pg_atomic_unlocked_test_flag(&flag))
		elog(ERROR, "flag: unexpectedly set");

	if (!pg_atomic_test_set_flag(&flag))
		elog(ERROR, "flag: couldn't set");

	if (pg_atomic_unlocked_test_flag(&flag))
		elog(ERROR, "flag: unexpectedly unset");

	if (pg_atomic_test_set_flag(&flag))
		elog(ERROR, "flag: set spuriously #2");

	pg_atomic_clear_flag(&flag);

	if (!pg_atomic_unlocked_test_flag(&flag))
		elog(ERROR, "flag: unexpectedly set #2");

	if (!pg_atomic_test_set_flag(&flag))
		elog(ERROR, "flag: couldn't set");

	pg_atomic_clear_flag(&flag);
}
Пример #2
0
void cfs_lock_file(FileMap* map, char const* file_path)
{
	long delay = CFS_LOCK_MIN_TIMEOUT;
	while (true) { 
		uint64 count = pg_atomic_fetch_add_u32(&map->lock, 1);
		if (count < CFS_GC_LOCK) {
			break;
		} 
		if (InRecovery) { 
			/* Uhhh... looks like last GC was interrupted.
			 * Try to recover file
			 */
			char* map_bck_path = psprintf("%s.map.bck", file_path);
			char* file_bck_path = psprintf("%s.bck", file_path);
			if (access(file_bck_path, R_OK) != 0) {
				/* There is no backup file: new map should be constructed */					
				int md2 = open(map_bck_path, O_RDWR|PG_BINARY, 0);
				if (md2 >= 0) { 
					/* Recover map */
					if (!cfs_read_file(md2, map, sizeof(FileMap))) { 
						elog(LOG, "Failed to read file %s: %m", map_bck_path);
					}
					close(md2);
				} 
			} else { 
				/* Presence of backup file means that we still have unchanged data and map files.
				 * Just remove backup files, grab lock and continue processing
				 */
				unlink(file_bck_path);
				unlink(map_bck_path);
			}
			pfree(file_bck_path);
			pfree(map_bck_path);
			break;
		}
		pg_atomic_fetch_sub_u32(&map->lock, 1);
		pg_usleep(delay);
		if (delay < CFS_LOCK_MAX_TIMEOUT) { 
			delay *= 2;
		}
	}
	if (IsUnderPostmaster && cfs_gc_workers != 0 && pg_atomic_test_set_flag(&cfs_state->gc_started))
	{
		cfs_start_background_gc();
	}
}
Пример #3
0
Datum cfs_start_gc(PG_FUNCTION_ARGS)
{
	int i = 0;

	if (cfs_gc_workers == 0 && pg_atomic_test_set_flag(&cfs_state->gc_started)) 
	{
		int j;
		BackgroundWorkerHandle** handles;

		cfs_stop = true; /* do just one iteration */	   

		cfs_state->max_iterations = 1;
		cfs_state->n_workers = PG_GETARG_INT32(0);
		handles = (BackgroundWorkerHandle**)palloc(cfs_state->n_workers*sizeof(BackgroundWorkerHandle*));		

		for (i = 0; i < cfs_state->n_workers; i++) {
			BackgroundWorker worker;
			MemSet(&worker, 0, sizeof(worker));
			sprintf(worker.bgw_name, "cfs-worker-%d", i);
			worker.bgw_flags = BGWORKER_SHMEM_ACCESS;
			worker.bgw_start_time = BgWorkerStart_ConsistentState;
			worker.bgw_restart_time = 1;
			worker.bgw_main = cfs_bgworker_main;
			worker.bgw_main_arg = Int32GetDatum(i);
			if (!RegisterDynamicBackgroundWorker(&worker, &handles[i])) { 
				break;
			}
		}
		for (j = 0; j < i; j++) {
			WaitForBackgroundWorkerShutdown(handles[j]);
		}
		pfree(handles);
		pg_atomic_clear_flag(&cfs_state->gc_started);
	}
	PG_RETURN_INT32(i);
}