// 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 "malloc.h"

static Lock finlock;

// 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
{
	void **key;
	Finalizer **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
};

static void
addfintab(Fintab *t, void *k, Finalizer *v)
{
	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] = v;
}

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

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

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

static Fintab fintab;

// add finalizer; caller is responsible for making sure not already in table
void
runtime·addfinalizer(void *p, void (*f)(void*), int32 nret)
{
	Fintab newtab;
	int32 i;
	uint32 *ref;
	byte *base;
	Finalizer *e;
	
	e = nil;
	if(f != nil) {
		e = runtime·mal(sizeof *e);
		e->fn = f;
		e->nret = nret;
	}

	runtime·lock(&finlock);
	if(!runtime·mlookup(p, &base, nil, nil, &ref) || p != base) {
		runtime·unlock(&finlock);
		runtime·throw("addfinalizer on invalid pointer");
	}
	if(f == nil) {
		if(*ref & RefHasFinalizer) {
			lookfintab(&fintab, p, 1);
			*ref &= ~RefHasFinalizer;
		}
		runtime·unlock(&finlock);
		return;
	}

	if(*ref & RefHasFinalizer) {
		runtime·unlock(&finlock);
		runtime·throw("double finalizer");
	}
	*ref |= RefHasFinalizer;

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

		runtime·memclr((byte*)&newtab, sizeof newtab);
		newtab.max = fintab.max;
		if(newtab.max == 0)
			newtab.max = 3*3*3;
		else if(fintab.ndead < fintab.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], RefNoPointers, 0, 1);
		newtab.val = runtime·mallocgc(newtab.max*sizeof newtab.val[0], 0, 0, 1);

		for(i=0; i<fintab.max; i++) {
			void *k;

			k = fintab.key[i];
			if(k != nil && k != (void*)-1)
				addfintab(&newtab, k, fintab.val[i]);
		}
		runtime·free(fintab.key);
		runtime·free(fintab.val);
		fintab = newtab;
	}

	addfintab(&fintab, p, e);
	runtime·unlock(&finlock);
}

// get finalizer; if del, delete finalizer.
// caller is responsible for updating RefHasFinalizer bit.
Finalizer*
runtime·getfinalizer(void *p, bool del)
{
	Finalizer *f;
	
	runtime·lock(&finlock);
	f = lookfintab(&fintab, p, del);
	runtime·unlock(&finlock);
	return f;
}

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

	runtime·lock(&finlock);
	key = fintab.key;
	ekey = key + fintab.max;
	for(; key < ekey; key++)
		if(*key != nil && *key != ((void*)-1))
			fn(*key);
	runtime·unlock(&finlock);
}
