// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"
#include "arch.h"
#include "malloc.h"

enum { debug = 0 };

typedef struct Fin Fin;
struct Fin
{
	void (*fn)(void*);
	int32 nret;
};

// Finalizer hash table.  Direct hash, linear scan, at most 3/4 full.
// Table size is power of 3 so that hash can be key % max.
// Key[i] == (void*)-1 denotes free but formerly occupied entry
// (doesn't stop the linear scan).
// Key and val are separate tables because the garbage collector
// must be instructed to ignore the pointers in key but follow the
// pointers in val.
typedef struct Fintab Fintab;
struct Fintab
{
	Lock;
	void **key;
	Fin *val;
	int32 nkey;	// number of non-nil entries in key
	int32 ndead;	// number of dead (-1) entries in key
	int32 max;	// size of key, val allocations
};

#define TABSZ 17
#define TAB(p) (&fintab[((uintptr)(p)>>3)%TABSZ])

static struct {
	Fintab;
	uint8 pad[CacheLineSize - sizeof(Fintab)];	
} fintab[TABSZ];

static void
addfintab(Fintab *t, void *k, void (*fn)(void*), int32 nret)
{
	int32 i, j;

	i = (uintptr)k % (uintptr)t->max;
	for(j=0; j<t->max; j++) {
		if(t->key[i] == nil) {
			t->nkey++;
			goto ret;
		}
		if(t->key[i] == (void*)-1) {
			t->ndead--;
			goto ret;
		}
		if(++i == t->max)
			i = 0;
	}

	// cannot happen - table is known to be non-full
	runtime·throw("finalizer table inconsistent");

ret:
	t->key[i] = k;
	t->val[i].fn = fn;
	t->val[i].nret = nret;
}

static bool
lookfintab(Fintab *t, void *k, bool del, Fin *f)
{
	int32 i, j;

	if(t->max == 0)
		return false;
	i = (uintptr)k % (uintptr)t->max;
	for(j=0; j<t->max; j++) {
		if(t->key[i] == nil)
			return false;
		if(t->key[i] == k) {
			if(f)
				*f = t->val[i];
			if(del) {
				t->key[i] = (void*)-1;
				t->val[i].fn = nil;
				t->val[i].nret = 0;
				t->ndead++;
			}
			return true;
		}
		if(++i == t->max)
			i = 0;
	}

	// cannot happen - table is known to be non-full
	runtime·throw("finalizer table inconsistent");
	return false;
}

static void
resizefintab(Fintab *tab)
{
	Fintab newtab;
	void *k;
	int32 i;

	runtime·memclr((byte*)&newtab, sizeof newtab);
	newtab.max = tab->max;
	if(newtab.max == 0)
		newtab.max = 3*3*3;
	else if(tab->ndead < tab->nkey/2) {
		// grow table if not many dead values.
		// otherwise just rehash into table of same size.
		newtab.max *= 3;
	}
	
	newtab.key = runtime·mallocgc(newtab.max*sizeof newtab.key[0], FlagNoPointers, 0, 1);
	newtab.val = runtime·mallocgc(newtab.max*sizeof newtab.val[0], 0, 0, 1);
	
	for(i=0; i<tab->max; i++) {
		k = tab->key[i];
		if(k != nil && k != (void*)-1)
			addfintab(&newtab, k, tab->val[i].fn, tab->val[i].nret);
	}
	
	runtime·free(tab->key);
	runtime·free(tab->val);
	
	tab->key = newtab.key;
	tab->val = newtab.val;
	tab->nkey = newtab.nkey;
	tab->ndead = newtab.ndead;
	tab->max = newtab.max;
}

bool
runtime·addfinalizer(void *p, void (*f)(void*), int32 nret)
{
	Fintab *tab;
	byte *base;
	
	if(debug) {
		if(!runtime·mlookup(p, &base, nil, nil) || p != base)
			runtime·throw("addfinalizer on invalid pointer");
	}
	
	tab = TAB(p);
	runtime·lock(tab);
	if(f == nil) {
		if(lookfintab(tab, p, true, nil))
			runtime·setblockspecial(p, false);
		runtime·unlock(tab);
		return true;
	}

	if(lookfintab(tab, p, false, nil)) {
		runtime·unlock(tab);
		return false;
	}

	if(tab->nkey >= tab->max/2+tab->max/4) {
		// keep table at most 3/4 full:
		// allocate new table and rehash.
		resizefintab(tab);
	}

	addfintab(tab, p, f, nret);
	runtime·setblockspecial(p, true);
	runtime·unlock(tab);
	return true;
}

// get finalizer; if del, delete finalizer.
// caller is responsible for updating RefHasFinalizer (special) bit.
bool
runtime·getfinalizer(void *p, bool del, void (**fn)(void*), int32 *nret)
{
	Fintab *tab;
	bool res;
	Fin f;
	
	tab = TAB(p);
	runtime·lock(tab);
	res = lookfintab(tab, p, del, &f);
	runtime·unlock(tab);
	if(res==false)
		return false;
	*fn = f.fn;
	*nret = f.nret;
	return true;
}

void
runtime·walkfintab(void (*fn)(void*))
{
	void **key;
	void **ekey;
	int32 i;

	for(i=0; i<TABSZ; i++) {
		runtime·lock(&fintab[i]);
		key = fintab[i].key;
		ekey = key + fintab[i].max;
		for(; key < ekey; key++)
			if(*key != nil && *key != ((void*)-1))
				fn(*key);
		runtime·unlock(&fintab[i]);
	}
}
