Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / simcore / callback.c
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: callback.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
*
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ========== Copyright Header End ============================================
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "@(#)callback.c 1.2 06/09/27 SMI"
#include <stdlib.h>
#include <pthread.h>
#include "list.h"
#include "allocate.h"
#include "basics.h"
#include "callback.h"
typedef struct {
callback_type_t type;
cb_func_t *cb_func;
void *cb_arg;
} cb_entry_t;
typedef LIST_DEF(cb_list_t, cb_entry_t);
static cb_list_t cb_list;
static pthread_mutex_t cb_lock;
void
callback_fire(callback_type_t type)
{
int i;
/* can't grab cb_lock as funcs call callback_delete()... */
for (i = 0; i < cb_list.count; i++) {
cb_entry_t *p;
p = LIST_ENTRY(cb_list, i);
if (p->type == type)
(*p->cb_func)(p->cb_arg);
}
}
void
callback_register(callback_type_t type, cb_func_t func, void *arg)
{
cb_entry_t *p;
int i;
pthread_mutex_lock(&cb_lock);
/* Check "free list". */
for (i = 0, p = NULL; i < cb_list.count; i++) {
cb_entry_t *p1;
p1 = LIST_ENTRY(cb_list, i);
if (p1->type == CB_None) {
p = p1;
break;
}
}
/* Allocate a new one? */
if (p == NULL)
p = LIST_ADD(cb_list, cb_entry_t);
p->type = type;
p->cb_func = func;
p->cb_arg = arg;
pthread_mutex_unlock(&cb_lock);
}
void
callback_delete(cb_func_t func)
{
int i;
pthread_mutex_lock(&cb_lock);
for (i = 0; i < cb_list.count; i++) {
cb_entry_t *p;
p = LIST_ENTRY(cb_list, i);
if (p->cb_func == func)
p->type = CB_None; /* Onto "free list". */
}
pthread_mutex_unlock(&cb_lock);
}
void
callback_init()
{
pthread_mutex_init(&cb_lock, NULL);
}