diff --git a/src/lam/lfc/list.h b/src/lam/lfc/list.h index 17908682f7..61a25df79a 100644 --- a/src/lam/lfc/list.h +++ b/src/lam/lfc/list.h @@ -64,31 +64,45 @@ void lam_list_destroy(lam_list_t *list); * Inlined accessor functions */ -#define lam_list_get_type(list) \ - ((lam_list_t*)list)->lam_list_type +static inline lam_list_type_t lam_list_get_type(lam_list_t* list) +{ + return list->lam_list_type; +} -#define lam_list_set_type(list, type) \ - (((lam_list_t*)list)->lam_list_type = type) +static inline void lam_list_set_type(lam_list_t* list, lam_list_type_t type) +{ + list->lam_list_type = type; +} -#define lam_list_get_size(list) \ - ((lam_list_t*)list)->lam_list_length +static inline size_t lam_list_get_size(lam_list_t* list) +{ + return list->lam_list_length; +} - /* set list size */ -#define lam_list_set_size(list,size) \ - ((lam_list_t*)list)->lam_list_length=(int)size; /* * Returns first item on list, but does not remove it from the list. */ -#define lam_list_get_first(list) \ - ((lam_list_t*)list)->lam_list_head - +static inline lam_list_item_t* lam_list_get_first(lam_list_t* list) +{ + return 0; +} /* * Returns last item on list, but does not remove it from the list. */ -#define lam_list_get_last(list) \ - ((lam_list_list_t*)list)->lam_list_tail +static inline lam_list_item_t* lam_list_get_last(lam_list_t* list) +{ + return 0; +} + +/* + * Returns end of list, an invalid list entry. + */ +static inline lam_list_item_t* lam_list_get_end(lam_list_t* list) +{ + return 0; +} /* diff --git a/src/mca/mpi/pml/pml.h b/src/mca/mpi/pml/pml.h index 06d7ec276f..75f858c47c 100644 --- a/src/mca/mpi/pml/pml.h +++ b/src/mca/mpi/pml/pml.h @@ -9,7 +9,6 @@ #include "lam/lam.h" #include "lam/lfc/list.h" -#include "mpi/proc/proc.h" #include "mpi/communicator/communicator.h" #include "mpi/datatype/datatype.h" #include "mpi/request/request.h" @@ -20,16 +19,15 @@ * PML module functions */ -typedef int (*mca_pml_base_query_fn_t)(int *priority, int *min_thread, - int* max_thread); -typedef struct mca_pml_1_0_0_t * - (*mca_pml_base_init_1_0_0_fn_t) - (struct lam_proc_t **procs, int nprocs, int *max_tag, int *max_cid); +typedef struct mca_pml_1_0_0_t * (*mca_pml_base_init_1_0_0_fn_t)(int* priority, int* min_thread, int* max_thread); +typedef int (*mca_pml_base_fini_fn_t)(void); /* * PML types */ +struct mca_ptl_t; + typedef uint64_t mca_pml_base_sequence_t; typedef uint64_t mca_pml_base_tstamp_t; typedef lam_list_t mca_pml_base_queue_t; @@ -39,28 +37,80 @@ typedef enum { MCA_PML_BASE_SEND_BUFFERED, MCA_PML_BASE_SEND_SYNCHRONOUS, MCA_PML_BASE_SEND_READY -} mca_pml_base_send_type_t; +} mca_pml_base_send_mode_t; + + +struct mca_pml_base_status_t { +}; +typedef struct mca_pml_base_status_t mca_pml_base_status_t; /* * PML interface functions */ +typedef int (*mca_pml_base_add_procs_fn_t)(struct lam_proc_t **procs, int nprocs); +typedef int (*mca_pml_base_add_ptls_fn_t)(struct mca_ptl_t **ptls, int nptls); typedef int (*mca_pml_base_progress_fn_t)(mca_pml_base_tstamp_t); +typedef int (*mca_pml_base_irecv_init_fn_t)( + void *buf, + size_t size, + struct lam_datatype_t *datatype, + int src, + int tag, + bool persistent, + struct lam_communicator_t* comm, + struct lam_request_t **request +); + +typedef int (*mca_pml_base_irecv_fn_t)( + void *buf, + size_t size, + struct lam_datatype_t *datatype, + int src, + int tag, + struct lam_communicator_t* comm, + struct lam_request_t **request +); + +typedef int (*mca_pml_base_isend_init_fn_t)( + void *buf, + size_t size, + struct lam_datatype_t *datatype, + int dst, + int tag, + mca_pml_base_send_mode_t mode, + bool persistent, + struct lam_communicator_t* comm, + struct lam_request_t **request +); + typedef int (*mca_pml_base_isend_fn_t)( void *buf, size_t size, struct lam_datatype_t *datatype, - int dest, + int dst, int tag, + mca_pml_base_send_mode_t mode, struct lam_communicator_t* comm, - mca_pml_base_send_type_t type, struct lam_request_t **request ); -typedef int (*mca_pml_base_addprocs_fn_t)(lam_proc_t **procs, int nprocs); +typedef int (*mca_pml_base_start_fn_t)( + lam_request_t* request +); +typedef int (*mca_pml_base_test_fn_t)( + lam_request_t** request, + int count, + int *completed +); + +typedef int (*mca_pml_base_wait_fn_t)( + lam_request_t* request, + mca_pml_base_status_t* status +); /* * PML module definition. @@ -69,8 +119,6 @@ typedef int (*mca_pml_base_addprocs_fn_t)(lam_proc_t **procs, int nprocs); struct mca_pml_base_module_1_0_0_t { mca_base_module_t pmlm_version; mca_base_module_data_1_0_0_t pmlm_data; - - mca_pml_base_query_fn_t pmlm_query; mca_pml_base_init_1_0_0_fn_t pmlm_init; }; typedef struct mca_pml_base_module_1_0_0_t mca_pml_base_module_1_0_0_t; @@ -82,12 +130,23 @@ typedef struct mca_pml_base_module_1_0_0_t mca_pml_base_module_1_0_0_t; */ struct mca_pml_1_0_0_t { - mca_pml_base_addprocs_fn_t pml_addprocs; - mca_pml_base_isend_fn_t pml_isend; - mca_pml_base_progress_fn_t pml_progress; + + mca_pml_base_add_procs_fn_t pml_add_procs; + mca_pml_base_add_ptls_fn_t pml_add_ptls; + mca_pml_base_fini_fn_t pml_fini; + + mca_pml_base_irecv_init_fn_t pml_irecv_init; + mca_pml_base_irecv_fn_t pml_irecv; + mca_pml_base_isend_init_fn_t pml_isend_init; + mca_pml_base_isend_fn_t pml_isend; + mca_pml_base_progress_fn_t pml_progress; + mca_pml_base_start_fn_t pml_start; + mca_pml_base_test_fn_t pml_test; + mca_pml_base_wait_fn_t pml_wait; + }; typedef struct mca_pml_1_0_0_t mca_pml_1_0_0_t; - +typedef struct mca_pml_1_0_0_t mca_pml_t; /* * Macro for use in modules that are of type pml v1.0.0 @@ -108,7 +167,6 @@ extern "C" { #endif int mca_pml_base_close(void); int mca_pml_base_open(lam_cmd_line_t *cmd); - int mca_pml_base_query(void); int mca_pml_base_init(void); #if defined(c_plusplus) || defined(__cplusplus) } diff --git a/src/mca/mpi/pml/teg/src/pml_teg.c b/src/mca/mpi/pml/teg/src/pml_teg.c index 44134603bb..7d19611944 100644 --- a/src/mca/mpi/pml/teg/src/pml_teg.c +++ b/src/mca/mpi/pml/teg/src/pml_teg.c @@ -2,7 +2,7 @@ #include "mca/mpi/pml/base/pml_base_recvreq.h" #include "pml_teg.h" -#define mca_teg_param_register(n,v) \ +#define mca_pml_teg_param_register_int(n,v) \ mca_base_param_lookup_int( \ mca_base_param_register_int("pml","teg",n,0,v)) @@ -32,72 +32,39 @@ mca_pml_base_module_1_0_0_t mca_pml_teg_module = { false }, - - mca_pml_teg_query, /* module query */ + mca_pml_teg_init /* module init */ }; -mca_pml_teg_1_0_0_t mca_pml_teg = { +mca_pml_teg_t mca_pml_teg = { { - mca_pml_teg_addprocs, + mca_pml_teg_add_procs, + mca_pml_teg_add_ptls, + mca_pml_teg_fini, + mca_pml_teg_irecv_init, + mca_pml_teg_irecv, + mca_pml_teg_isend_init, mca_pml_teg_isend, - mca_pml_teg_progress + mca_pml_teg_progress, + mca_pml_teg_start, + mca_pml_teg_test, + mca_pml_teg_wait, } }; int mca_pml_teg_open(lam_cmd_line_t* cmd_line) { - mca_pml_teg.teg_send_free_list_min_pages = - mca_pml_teg_register_int("send_free_list_min_pages", 10); - mca_pml_teg.teg_send_free_list_max_pages = - mca_pml_teg_register_int("send_free_list_max_pages", -1); - mca_pml_teg.teg_send_free_list_inc_pages = - mca_pml_teg_register_int("send_free_list_inc_pages", 1); - mca_pml_teg.teg_recv_free_list_min_pages = - mca_pml_teg_register_int("recv_free_list_min_pages", 10); - mca_pml_teg.teg_recv_free_list_max_pages = - mca_pml_teg_register_int("recv_free_list_max_pages", -1); - mca_pml_teg.teg_recv_free_list_inc_pages = - mca_pml_teg_register_int("recv_free_list_inc_pages", 1); return LAM_SUCCESS; } -mca_pml_1_0_0_t* mca_pml_teg_init( - struct lam_proc_t **procs, - int nprocs, - int *max_tag, - int *max_cid) +mca_pml_1_0_0_t* mca_pml_teg_init(int* priority, int* min_thread, int* max_thread) { - int rc; - lam_free_list_init(&mca_pml_teg.teg_send_free_list); - if((rc = lam_free_list_init_with( - &mca_pml_teg.teg_send_free_list, - sizeof(mca_pml_base_send_request_t), - mca_pml_teg.teg_send_free_list_min_pages, - mca_pml_teg.teg_send_free_list_max_pages, - mca_pml_teg.teg_send_free_list_inc_pages, - NULL)) != LAM_SUCCESS) - { - return NULL; - } - - lam_free_list_init(&mca_pml_teg.teg_recv_free_list); - if((rc = lam_free_list_init_with( - &mca_pml_teg.teg_recv_free_list, - sizeof(mca_pml_base_recv_request_t), - mca_pml_teg.teg_recv_free_list_min_pages, - mca_pml_teg.teg_recv_free_list_max_pages, - mca_pml_teg.teg_recv_free_list_inc_pages, - NULL)) != LAM_SUCCESS) - { - return NULL; - } - - lam_free_list_init(&mca_pml_teg.teg_incomplete_sends); + *priority = 0; + *min_thread = 0; + *max_thread = 0; return &mca_pml_teg.super; } - - + diff --git a/src/mca/mpi/pml/teg/src/pml_teg.h b/src/mca/mpi/pml/teg/src/pml_teg.h index 2bd22da444..e54302deb8 100644 --- a/src/mca/mpi/pml/teg/src/pml_teg.h +++ b/src/mca/mpi/pml/teg/src/pml_teg.h @@ -24,69 +24,86 @@ extern int mca_pml_teg_open( extern int mca_pml_teg_close(void); -extern int mca_pml_teg_query( - int *priority, - int *min_thread, - int* max_thread -); - extern mca_pml_1_0_0_t* mca_pml_teg_init( - lam_proc_t **procs, - int nprocs, + int *priority, int *max_tag, int *max_cid ); + /* * TEG PML Interface - * - * JMS: Tim--Note that you don't have to do versioning here. - * Versioning is only for the MCA framework (i.e., able to load - * modules of different versions). This type is going to be used - * specifically within your module, and the framework will never see - * it. Ergo, no other teg modules (even those of different versions) - * will ever see it, either. So while you can do the 1_0_0 stuff - * here, it isn't strictly necessary. */ -struct mca_pml_teg_1_0_0_t { - mca_pml_1_0_0_t super; - - /* send request free list and parameters */ - lam_free_list_t teg_send_free_list; - int teg_send_free_list_min_pages; - int teg_send_free_list_max_pages; - int teg_send_free_list_inc_pages; - - /* recv request free list and parameters */ - lam_free_list_t teg_recv_free_list; - int teg_recv_free_list_min_pages; - int teg_recv_free_list_max_pages; - int teg_recv_free_list_inc_pages; +struct mca_pml_teg_t { + mca_pml_t super; /* incomplete posted sends */ lam_list_t teg_incomplete_sends; lam_mutex_t teg_lock; }; -typedef struct mca_pml_teg_1_0_0_t mca_pml_teg_1_0_0_t; +typedef struct mca_pml_teg_t mca_pml_teg_t; -extern mca_pml_teg_1_0_0_t mca_pml_teg; +extern mca_pml_teg_t mca_pml_teg; /* * PML interface functions. */ -extern mca_pml_teg_1_0_0_t mca_pml_teg_1_0_0_0; +extern int mca_pml_teg_add_procs( + struct lam_proc_t **procs, + int nprocs +); + +extern int mca_pml_teg_add_ptls( + struct mca_ptl_t **ptls, + int nptls +); + +extern int mca_pml_teg_fini(void); + +extern int mca_pml_teg_isend_init( + void *buf, + size_t size, + struct lam_datatype_t *datatype, + int dst, + int tag, + mca_pml_base_send_mode_t mode, + bool persistent, + struct lam_communicator_t* comm, + struct lam_request_t **request +); extern int mca_pml_teg_isend( void *buf, size_t size, struct lam_datatype_t *datatype, - int dest, + int dst, + int tag, + mca_pml_base_send_mode_t mode, + struct lam_communicator_t* comm, + struct lam_request_t **request +); + +extern int mca_pml_teg_irecv_init( + void *buf, + size_t size, + struct lam_datatype_t *datatype, + int src, + int tag, + bool persistent, + struct lam_communicator_t* comm, + struct lam_request_t **request +); + +extern int mca_pml_teg_irecv( + void *buf, + size_t size, + struct lam_datatype_t *datatype, + int src, int tag, struct lam_communicator_t* comm, - mca_pml_base_request_type_t req_type, struct lam_request_t **request ); @@ -94,10 +111,21 @@ extern int mca_pml_teg_progress( mca_pml_base_tstamp_t tstamp ); -extern int mca_pml_teg_addprocs( - lam_proc_t **procs, - int nprocs +extern int mca_pml_teg_start( + lam_request_t* request ); + +extern int mca_pml_teg_test( + lam_request_t** request, + int count, + int *completed +); + +extern int mca_pml_teg_wait( + lam_request_t* request, + mca_pml_base_status_t* status +); + #endif diff --git a/src/mca/mpi/pml/teg/src/pml_teg_isend.c b/src/mca/mpi/pml/teg/src/pml_teg_isend.c index eec9d6e464..9b60c9e7d6 100644 --- a/src/mca/mpi/pml/teg/src/pml_teg_isend.c +++ b/src/mca/mpi/pml/teg/src/pml_teg_isend.c @@ -2,24 +2,27 @@ * $HEADER$ */ -#include "mca/mpi/pml/base/pml_base_sendreq.h" #include "pml_teg.h" +#include "pml_teg_proc.h" +#include "pml_teg_sendreq.h" -int mca_pml_teg_isend( + +int mca_pml_teg_isend_init( void *buf, size_t size, lam_datatype_t *datatype, - int dest, + int dst, int tag, + mca_pml_base_send_mode_t sendmode, + bool persistent, lam_communicator_t* comm, - mca_pml_base_send_type_t req_type, lam_request_t **request) { int rc; - mca_pml_base_send_request_t* sendreq = - (mca_pml_base_send_request_t*)lam_free_list_get(&mca_pml_teg.teg_send_free_list, &rc); - if(sendreq == 0) + mca_pml_base_send_request_t* sendreq; + mca_pml_proc_t *proc = mca_pml_teg_proc_lookup_remote(comm,dst); + if((rc = mca_pml_teg_send_request_alloc(proc, &sendreq)) != LAM_SUCCESS) return rc; mca_pml_base_send_request_rinit( @@ -27,10 +30,43 @@ int mca_pml_teg_isend( buf, size, datatype, - dest, + dst, tag, comm, - req_type, + sendmode, + persistent + ); + + *request = (lam_request_t*)sendreq; + return LAM_SUCCESS; +} + + +int mca_pml_teg_isend( + void *buf, + size_t size, + lam_datatype_t *datatype, + int dst, + int tag, + mca_pml_base_send_mode_t sendmode, + lam_communicator_t* comm, + lam_request_t **request) +{ + int rc; + mca_pml_base_send_request_t* sendreq; + mca_pml_proc_t* proc = mca_pml_teg_proc_lookup_remote(comm,dst); + if((rc = mca_pml_teg_send_request_alloc(proc, &sendreq)) != LAM_SUCCESS) + return rc; + + mca_pml_base_send_request_rinit( + sendreq, + buf, + size, + datatype, + dst, + tag, + comm, + sendmode, false ); diff --git a/src/mca/mpi/pml/teg/src/pml_teg_proc.h b/src/mca/mpi/pml/teg/src/pml_teg_proc.h index 6000b29347..008821a573 100644 --- a/src/mca/mpi/pml/teg/src/pml_teg_proc.h +++ b/src/mca/mpi/pml/teg/src/pml_teg_proc.h @@ -5,6 +5,8 @@ #ifndef MCA_PML_PROC_H #define MCA_PML_PROC_H +#include "mpi/communicator/communicator.h" +#include "mpi/group/group.h" #include "mpi/proc/proc.h" #include "pml_teg_ptl_array.h" @@ -27,5 +29,17 @@ typedef struct mca_pml_proc_t mca_pml_proc_t; void mca_pml_teg_proc_init(mca_pml_proc_t*); void mca_pml_teg_proc_destroy(mca_pml_proc_t*); +static inline mca_pml_proc_t* mca_pml_teg_proc_lookup_local(lam_communicator_t* comm, int rank) +{ + lam_proc_t* proc = comm->c_local_group->g_procs[rank]; + return proc->proc_pml; +} + +static inline mca_pml_proc_t* mca_pml_teg_proc_lookup_remote(lam_communicator_t* comm, int rank) +{ + lam_proc_t* proc = comm->c_remote_group->g_procs[rank]; + return proc->proc_pml; +} + #endif diff --git a/src/mca/mpi/pml/teg/src/pml_teg_sendreq.c b/src/mca/mpi/pml/teg/src/pml_teg_sendreq.c index 1244e84301..17f49d8a36 100644 --- a/src/mca/mpi/pml/teg/src/pml_teg_sendreq.c +++ b/src/mca/mpi/pml/teg/src/pml_teg_sendreq.c @@ -5,9 +5,15 @@ #include "lam/constants.h" #include "mca/mpi/ptl/ptl.h" -#include "mca/mpi/pml/base/pml_base_sendreq.h" #include "pml_teg.h" #include "pml_teg_proc.h" +#include "pml_teg_sendreq.h" + + +int mca_pml_teg_send_request_alloc(mca_pml_proc_t* proc, mca_pml_base_send_request_t** sendreq) +{ + return LAM_SUCCESS; +} /* @@ -51,28 +57,6 @@ int mca_pml_teg_send_request_schedule(mca_pml_base_send_request_t* req, bool* co lam_proc_t *proc = lam_comm_lookup_peer(req->super.req_communicator, req->super.req_peer); mca_pml_proc_t* proc_pml = proc->proc_pml; - /* allocate first fragment, if the first PTL in the list - * cannot allocate resources for the fragment, try the next - * available. - */ - if(req->req_frags_allocated == 0) { - size_t num_ptl_avail = proc_pml->proc_ptl_first.ptl_size; - size_t i; - for(i = 0; i < num_ptl_avail; i++) { - mca_ptl_info_t* ptl_info = mca_ptl_array_get_next(&proc_pml->proc_ptl_first); - mca_ptl_t* ptl = ptl_info->ptl; - int rc = ptl->ptl_fragment(ptl, req, ptl->ptl_frag_first_size); - if (rc == LAM_SUCCESS) - break; - else if (rc != LAM_ERR_TEMP_OUT_OF_RESOURCE) - return rc; - } - /* has first fragment been allocated? */ - if(req->req_frags_allocated == 0) { - *complete = false; - return LAM_SUCCESS; - } - } /* allocate remaining bytes to PTLs */ size_t bytes_remaining = req->req_length - req->req_bytes_fragmented; @@ -116,7 +100,7 @@ int mca_pml_teg_send_request_schedule(mca_pml_base_send_request_t* req, bool* co * */ -void mca_pml_teg_send_request_push() +int mca_pml_teg_send_request_progress(void) { THREAD_LOCK(&mca_pml_teg.teg_lock); mca_pml_base_send_request_t* req; @@ -127,15 +111,16 @@ void mca_pml_teg_send_request_push() bool complete; int rc = mca_pml_teg_send_request_schedule(req, &complete); if(rc != LAM_SUCCESS) { - // FIX - exit(-1); + THREAD_UNLOCK(&mca_pml_teg.teg_lock); + return rc; } if(complete) { - req = (mca_pml_base_send_request_t*)lam_dbl_remove( + req = (mca_pml_base_send_request_t*)lam_list_remove( &mca_pml_teg.teg_incomplete_sends, (lam_list_item_t*)req); } } THREAD_UNLOCK(&mca_pml_teg.teg_lock); + return LAM_SUCCESS; } diff --git a/src/mca/mpi/pml/teg/src/pml_teg_sendreq.h b/src/mca/mpi/pml/teg/src/pml_teg_sendreq.h index 8c29a89ec8..6c89997efd 100644 --- a/src/mca/mpi/pml/teg/src/pml_teg_sendreq.h +++ b/src/mca/mpi/pml/teg/src/pml_teg_sendreq.h @@ -5,11 +5,17 @@ #ifndef LAM_PML_TEG_SEND_REQUEST_H #define LAM_PML_TEG_SEND_REQUEST_H -#include "mca/pml/base/pml_base_sendreq.h" +#include "mca/mpi/pml/base/pml_base_sendreq.h" +#include "mca/mpi/pml/base/pml_base_sendfrag.h" + +int mca_pml_teg_send_request_alloc( + mca_pml_proc_t*, + mca_pml_base_send_request_t** +); int mca_pml_teg_send_request_start(mca_pml_base_send_request_t* req); -int mca_pml_teg_send_request_schedule(mca_pml_base_send_request_t* req, bool_t* complete) -int mca_pml_teg_send_request_progress(); +int mca_pml_teg_send_request_schedule(mca_pml_base_send_request_t* req, bool* complete); +int mca_pml_teg_send_request_progress(void); #endif diff --git a/src/mca/mpi/ptl/ptl.h b/src/mca/mpi/ptl/ptl.h index 1a2344df6e..ed2ebe29e8 100644 --- a/src/mca/mpi/ptl/ptl.h +++ b/src/mca/mpi/ptl/ptl.h @@ -25,13 +25,14 @@ typedef struct mca_ptl_1_0_0_t mca_ptl_t; * PTL module functions. */ -typedef int (*mca_ptl_query_fn_t)(int *priority, int *thread_min, int *thread_max); -typedef struct mca_ptl_1_0_0* (*mca_ptl_init_1_0_0_fn_t)(); +typedef bool (*mca_ptl_init_1_0_0_fn_t)(struct mca_ptl_1_0_0_t** ptls, int* num_ptls, int *thread_min, int *thread_max); +typedef int (*mca_ptl_fini_1_0_0_fn_t)(struct mca_ptl_1_0_0_t*); /* * PTL action functions. */ +typedef mca_pml_base_send_request_t* (*mca_ptl_send_request_alloc_fn_t)(mca_ptl_t*); typedef int (*mca_ptl_fragment_fn_t)(mca_ptl_t*, mca_pml_base_send_request_t*, size_t); typedef int (*mca_ptl_progress_fn_t)(mca_ptl_t*, mca_pml_base_tstamp_t); @@ -44,7 +45,6 @@ struct mca_ptl_module_1_0_0_t { mca_base_module_t ptlm_version; mca_base_module_data_1_0_0_t ptlm_data; - mca_ptl_query_fn_t ptlm_query; mca_ptl_init_1_0_0_fn_t ptlm_init; }; @@ -66,11 +66,13 @@ struct mca_ptl_1_0_0_t { size_t ptl_endpoint_count; /* number endpoints supported by this CDI */ /* PTL function table */ - mca_ptl_fragment_fn_t ptl_fragment; - mca_ptl_progress_fn_t ptl_progress; + mca_ptl_send_request_alloc_fn_t ptl_send_request_alloc; + mca_ptl_fragment_fn_t ptl_fragment; + mca_ptl_progress_fn_t ptl_progress; }; + typedef struct mca_ptl_1_0_0_t mca_ptl_1_0_0_t; /*