<commit_before>/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
 ****************************************************************************
 * (C) 2003 - <NAME> - Intel Research Cambridge
 * (C) 2005 - <NAME> - Intel Research Cambridge
 ****************************************************************************
 *
 *        File: events.c
 *      Author: <NAME> (<EMAIL>)
 *     Changes: <NAME> (<EMAIL>)
 *              
 *        Date: Jul 2003, changes Jun 2005
 * 
 * Environment: Xen Minimal OS
 * Description: Deals with events recieved on event channels
 *
 ****************************************************************************
 */

#include <os.h>
#include <mm.h>
#include <hypervisor.h>
#include <events.h>
#include <lib.h>

#define NR_EVS 1024

/* this represents a event handler. Chaining or sharing is not allowed */
typedef struct _ev_action_t {
	evtchn_handler_t handler;
	void *data;
    u32 count;
} ev_action_t;

static ev_action_t ev_actions[NR_EVS];
void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);

static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];

void unbind_all_ports(void)
{
    int i;

    for (i = 0; i < NR_EVS; i++)
    {
        if (test_and_clear_bit(i, bound_ports))
        {
            struct evtchn_close close;
            mask_evtchn(i);
            close.port = i;
            HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
        }
    }
}
  
/*
 * Demux events to different handlers.
 */
int do_event(evtchn_port_t port, struct pt_regs *regs)
{
    ev_action_t  *action;
    if (port >= NR_EVS) {
        printk("Port number too large: %d\n", port);
		goto out;
    }

    action = &ev_actions[port];
    action->count++;

    /* call the handler */
	action->handler(port, regs, action->data);

 out:
	clear_evtchn(port);

    return 1;

}

evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
						  void *data)
{
 	if(ev_actions[port].handler != default_handler)
        printk("WARN: Handler for port %d already registered, replacing\n",
				port);

	ev_actions[port].data = data;
	wmb();
	ev_actions[port].handler = handler;<commit_msg>minios: clear the event before calling the handler since (especially in the SMP case) the handler may make another domain send an event again, and that must not be lost.<commit_after>/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
 ****************************************************************************
 * (C) 2003 - <NAME> - Intel Research Cambridge
 * (C) 2005 - <NAME> - Intel Research Cambridge
 ****************************************************************************
 *
 *        File: events.c
 *      Author: <NAME> (<EMAIL>)
 *     Changes: <NAME> (<EMAIL>)
 *              
 *        Date: Jul 2003, changes Jun 2005
 * 
 * Environment: Xen Minimal OS
 * Description: Deals with events recieved on event channels
 *
 ****************************************************************************
 */

#include <os.h>
#include <mm.h>
#include <hypervisor.h>
#include <events.h>
#include <lib.h>

#define NR_EVS 1024

/* this represents a event handler. Chaining or sharing is not allowed */
typedef struct _ev_action_t {
	evtchn_handler_t handler;
	void *data;
    u32 count;
} ev_action_t;

static ev_action_t ev_actions[NR_EVS];
void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);

static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];

void unbind_all_ports(void)
{
    int i;

    for (i = 0; i < NR_EVS; i++)
    {
        if (test_and_clear_bit(i, bound_ports))
        {
            struct evtchn_close close;
            mask_evtchn(i);
            close.port = i;
            HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
        }
    }
}
  
/*
 * Demux events to different handlers.
 */
int do_event(evtchn_port_t port, struct pt_regs *regs)
{
    ev_action_t  *action;

    clear_evtchn(port);

    if (port >= NR_EVS) {
        printk("Port number too large: %d\n", port);
        return 1;
    }

    action = &ev_actions[port];
    action->count++;

    /* call the handler */
	action->handler(port, regs, action->data);

    return 1;

}

evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
						  void *data)
{
 	if(ev_actions[port].handler != default_handler)
        printk("WARN: Handler for port %d already registered, replacing\n",
				port);

	ev_actions[port].data = data;
	wmb();
	ev_actions[port].handler = handler;
{'fraction_non_alphanumeric': 0.21148708815672307, 'fraction_numerical': 0.012243989314336599, 'mean_word_length': 3.3748782862706914, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5570796', 'n_tokens_mistral': 1524, 'n_tokens_neox': 1411, 'n_words': 373}