2022-04-25 10:57:21 +03:00
/*
* QEMU event - loop base
*
* Copyright ( C ) 2022 Red Hat Inc
*
* Authors :
* Stefan Hajnoczi < stefanha @ redhat . com >
* Nicolas Saenz Julienne < nsaenzju @ redhat . com >
*
* This work is licensed under the terms of the GNU GPL , version 2 or later .
* See the COPYING file in the top - level directory .
*/
# include "qemu/osdep.h"
# include "qom/object_interfaces.h"
# include "qapi/error.h"
2022-04-25 10:57:23 +03:00
# include "block/thread-pool.h"
2022-04-25 10:57:21 +03:00
# include "sysemu/event-loop-base.h"
typedef struct {
const char * name ;
ptrdiff_t offset ; /* field's byte offset in EventLoopBase struct */
} EventLoopBaseParamInfo ;
2022-04-25 10:57:23 +03:00
static void event_loop_base_instance_init ( Object * obj )
{
EventLoopBase * base = EVENT_LOOP_BASE ( obj ) ;
base - > thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT ;
}
2022-04-25 10:57:21 +03:00
static EventLoopBaseParamInfo aio_max_batch_info = {
" aio-max-batch " , offsetof ( EventLoopBase , aio_max_batch ) ,
} ;
2022-04-25 10:57:23 +03:00
static EventLoopBaseParamInfo thread_pool_min_info = {
" thread-pool-min " , offsetof ( EventLoopBase , thread_pool_min ) ,
} ;
static EventLoopBaseParamInfo thread_pool_max_info = {
" thread-pool-max " , offsetof ( EventLoopBase , thread_pool_max ) ,
} ;
2022-04-25 10:57:21 +03:00
static void event_loop_base_get_param ( Object * obj , Visitor * v ,
const char * name , void * opaque , Error * * errp )
{
EventLoopBase * event_loop_base = EVENT_LOOP_BASE ( obj ) ;
EventLoopBaseParamInfo * info = opaque ;
int64_t * field = ( void * ) event_loop_base + info - > offset ;
visit_type_int64 ( v , name , field , errp ) ;
}
static void event_loop_base_set_param ( Object * obj , Visitor * v ,
const char * name , void * opaque , Error * * errp )
{
EventLoopBaseClass * bc = EVENT_LOOP_BASE_GET_CLASS ( obj ) ;
EventLoopBase * base = EVENT_LOOP_BASE ( obj ) ;
EventLoopBaseParamInfo * info = opaque ;
int64_t * field = ( void * ) base + info - > offset ;
int64_t value ;
if ( ! visit_type_int64 ( v , name , & value , errp ) ) {
return ;
}
if ( value < 0 ) {
error_setg ( errp , " %s value must be in range [0, % " PRId64 " ] " ,
info - > name , INT64_MAX ) ;
return ;
}
* field = value ;
if ( bc - > update_params ) {
bc - > update_params ( base , errp ) ;
}
return ;
}
static void event_loop_base_complete ( UserCreatable * uc , Error * * errp )
{
EventLoopBaseClass * bc = EVENT_LOOP_BASE_GET_CLASS ( uc ) ;
EventLoopBase * base = EVENT_LOOP_BASE ( uc ) ;
if ( bc - > init ) {
bc - > init ( base , errp ) ;
}
}
2022-04-25 10:57:22 +03:00
static bool event_loop_base_can_be_deleted ( UserCreatable * uc )
{
EventLoopBaseClass * bc = EVENT_LOOP_BASE_GET_CLASS ( uc ) ;
EventLoopBase * backend = EVENT_LOOP_BASE ( uc ) ;
if ( bc - > can_be_deleted ) {
return bc - > can_be_deleted ( backend ) ;
}
return true ;
}
2022-04-25 10:57:21 +03:00
static void event_loop_base_class_init ( ObjectClass * klass , void * class_data )
{
UserCreatableClass * ucc = USER_CREATABLE_CLASS ( klass ) ;
ucc - > complete = event_loop_base_complete ;
2022-04-25 10:57:22 +03:00
ucc - > can_be_deleted = event_loop_base_can_be_deleted ;
2022-04-25 10:57:21 +03:00
object_class_property_add ( klass , " aio-max-batch " , " int " ,
event_loop_base_get_param ,
event_loop_base_set_param ,
NULL , & aio_max_batch_info ) ;
2022-04-25 10:57:23 +03:00
object_class_property_add ( klass , " thread-pool-min " , " int " ,
event_loop_base_get_param ,
event_loop_base_set_param ,
NULL , & thread_pool_min_info ) ;
object_class_property_add ( klass , " thread-pool-max " , " int " ,
event_loop_base_get_param ,
event_loop_base_set_param ,
NULL , & thread_pool_max_info ) ;
2022-04-25 10:57:21 +03:00
}
static const TypeInfo event_loop_base_info = {
. name = TYPE_EVENT_LOOP_BASE ,
. parent = TYPE_OBJECT ,
. instance_size = sizeof ( EventLoopBase ) ,
2022-04-25 10:57:23 +03:00
. instance_init = event_loop_base_instance_init ,
2022-04-25 10:57:21 +03:00
. class_size = sizeof ( EventLoopBaseClass ) ,
. class_init = event_loop_base_class_init ,
. abstract = true ,
. interfaces = ( InterfaceInfo [ ] ) {
{ TYPE_USER_CREATABLE } ,
{ }
}
} ;
static void register_types ( void )
{
type_register_static ( & event_loop_base_info ) ;
}
type_init ( register_types ) ;