1
1
1. fix a bug in pml_ob1_recvreq/sendreq.c, buffer was made defined where the request has already been released.
2. complete memchecker support for collective functions.
3. change the wrongly spelled function name of memchecker, i.e. '*_isaddressible' should be '*_isaddressable'

This commit was SVN r20043.
Этот коммит содержится в:
Shiqing Fan 2008-11-27 16:34:02 +00:00
родитель 017c0c526b
Коммит abd21b6d17
22 изменённых файлов: 255 добавлений и 73 удалений

Просмотреть файл

@ -65,19 +65,19 @@ static int mca_pml_ob1_recv_request_free(struct ompi_request_t** request)
&(recvreq->req_recv.req_base), PERUSE_RECV );
if( true == recvreq->req_recv.req_base.req_pml_complete ) {
/* make buffer defined when the request is compeleted,
and before releasing the objects. */
MEMCHECKER(
memchecker_call(&opal_memchecker_base_mem_defined,
recvreq->req_recv.req_base.req_addr,
recvreq->req_recv.req_base.req_count,
recvreq->req_recv.req_base.req_datatype);
);
MCA_PML_OB1_RECV_REQUEST_RETURN( recvreq );
}
OPAL_THREAD_UNLOCK(&ompi_request_lock);
/*
* Package successfully received, make user buffer accessable.
*/
MEMCHECKER(
memchecker_call(&opal_memchecker_base_mem_defined,
recvreq->req_recv.req_base.req_addr,
recvreq->req_recv.req_base.req_count,
recvreq->req_recv.req_base.req_datatype);
);
*request = MPI_REQUEST_NULL;
return OMPI_SUCCESS;
}

Просмотреть файл

@ -100,16 +100,20 @@ static int mca_pml_ob1_send_request_free(struct ompi_request_t** request)
&(sendreq->req_send.req_base), PERUSE_SEND );
if( true == sendreq->req_send.req_base.req_pml_complete ) {
/* make buffer defined when the request is compeleted,
and before releasing the objects. */
MEMCHECKER(
memchecker_call(&opal_memchecker_base_mem_defined,
sendreq->req_send.req_base.req_addr,
sendreq->req_send.req_base.req_count,
sendreq->req_send.req_base.req_datatype);
);
MCA_PML_OB1_SEND_REQUEST_RETURN( sendreq );
}
OPAL_THREAD_UNLOCK(&ompi_request_lock);
MEMCHECKER(
memchecker_call(&opal_memchecker_base_mem_defined,
sendreq->req_send.req_base.req_addr,
sendreq->req_send.req_base.req_count,
sendreq->req_send.req_base.req_datatype);
);
*request = MPI_REQUEST_NULL;
return OMPI_SUCCESS;
}

Просмотреть файл

@ -42,10 +42,22 @@ int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
int err;
MEMCHECKER(
memchecker_datatype(sendtype);
int rank;
ptrdiff_t ext;
rank = ompi_comm_rank(comm);
ompi_ddt_type_extent(recvtype, &ext);
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
memchecker_comm(comm);
/* check whether the actual send buffer is defined. */
if (MPI_IN_PLACE == sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined, recvbuf+rank*ext, recvcount, recvtype);
} else {
memchecker_datatype(sendtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
}
/* check whether the receive buffer is addressable. */
memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, recvcount, recvtype);
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -41,10 +41,31 @@ int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
int i, size, err;
MEMCHECKER(
memchecker_datatype(sendtype);
int rank;
ptrdiff_t ext;
rank = ompi_comm_rank(comm);
size = ompi_comm_size(comm);
ompi_ddt_type_extent(recvtype, &ext);
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
memchecker_comm (comm);
/* check whether the receive buffer is addressable. */
for (i = 0; i < size; i++) {
memchecker_call(&opal_memchecker_base_isaddressable,
recvbuf+displs[i]*ext,
recvcounts[i], recvtype);
}
/* check whether the actual send buffer is defined. */
if (MPI_IN_PLACE == sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined,
recvbuf+displs[rank]*ext,
recvcounts[rank], recvtype);
} else {
memchecker_datatype(sendtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -42,8 +42,17 @@ int MPI_Allreduce(void *sendbuf, void *recvbuf, int count,
MEMCHECKER(
memchecker_datatype(datatype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
memchecker_comm(comm);
/* check whether receive buffer is defined. */
memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, count, datatype);
/* check whether the actual send buffer is defined. */
if (MPI_IN_PLACE == sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined, recvbuf, count, datatype);
} else {
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -36,7 +36,7 @@ static const char FUNC_NAME[] = "MPI_Alltoall";
int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm)
{
int err;
@ -45,6 +45,7 @@ int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
memchecker_datatype(sendtype);
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, recvcount, recvtype);
memchecker_comm(comm);
);

Просмотреть файл

@ -43,14 +43,26 @@ int MPI_Alltoallv(void *sendbuf, int *sendcounts, int *sdispls,
int i, size, err;
MEMCHECKER(
size = ompi_comm_remote_size(comm);
ptrdiff_t recv_ext;
ptrdiff_t send_ext;
size = ompi_comm_size(comm);
ompi_ddt_type_extent(recvtype, &recv_ext);
ompi_ddt_type_extent(sendtype, &send_ext);
memchecker_datatype(sendtype);
memchecker_datatype(recvtype);
memchecker_comm(comm);
for ( i = 0; i < size; i++ ) {
memchecker_call(&opal_memchecker_base_isdefined, (char*)sendbuf+sdispls[i], sendcounts[i], sendtype);
memchecker_comm(comm);
/* check if send chunks are defined. */
memchecker_call(&opal_memchecker_base_isdefined,
sendbuf+sdispls[i]*send_ext,
sendcounts[i], sendtype);
/* check if receive chunks are addressable. */
memchecker_call(&opal_memchecker_base_isaddressable,
recvbuf+rdispls[i]*recv_ext,
recvcounts[i], recvtype);
}
);

Просмотреть файл

@ -43,12 +43,27 @@ int MPI_Alltoallw(void *sendbuf, int *sendcounts, int *sdispls,
int i, size, err;
MEMCHECKER(
size = ompi_comm_remote_size(comm);
ptrdiff_t recv_ext;
ptrdiff_t send_ext;
size = ompi_comm_size(comm);
memchecker_comm(comm);
for ( i = 0; i < size; i++ ) {
memchecker_datatype(sendtypes[i]);
memchecker_datatype(recvtypes[i]);
memchecker_call(&opal_memchecker_base_isdefined, (char*)sendbuf+sdispls[i], sendcounts[i], sendtypes[i]);
memchecker_comm(comm);
ompi_ddt_type_extent(sendtypes[i], &send_ext);
ompi_ddt_type_extent(recvtypes[i], &recv_ext);
memchecker_call(&opal_memchecker_base_isdefined,
sendbuf+sdispls[i]*send_ext,
sendcounts[i],
sendtypes[i]);
memchecker_call(&opal_memchecker_base_isaddressable,
recvbuf+sdispls[i]*recv_ext,
recvcounts[i],
recvtypes[i]);
}
);

Просмотреть файл

@ -40,8 +40,15 @@ int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype,
MEMCHECKER(
memchecker_datatype(datatype);
memchecker_call(&opal_memchecker_base_isdefined, buffer, count, datatype);
memchecker_comm(comm);
if( ompi_comm_rank(comm) == root || MPI_ROOT == root ) {
/* check whether root's send buffer is defined. */
memchecker_call(&opal_memchecker_base_isdefined, buffer, count, datatype);
}
if( MPI_PROC_NULL != root ) {
/* check whether receive buffer is addressable. */
memchecker_call(&opal_memchecker_base_isaddressable, buffer, count, datatype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -43,10 +43,25 @@ int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
int err;
MEMCHECKER(
memchecker_datatype(sendtype);
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
int rank;
ptrdiff_t ext;
rank = ompi_comm_rank(comm);
ompi_ddt_type_extent(recvtype, &ext);
memchecker_comm(comm);
if (ompi_comm_rank(comm) == root || MPI_ROOT == root) {
memchecker_datatype(recvtype);
/* check whether root's receive buffer is addressable/defined(MPI_IN_PLACE). */
if (MPI_IN_PLACE == sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined, recvbuf+rank*ext, recvcount, recvtype);
}
memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, recvcount, recvtype);
}
/* check whether the send buffer is defined. */
if (MPI_PROC_NULL != root && MPI_IN_PLACE != sendbuf) {
memchecker_datatype(sendtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -39,11 +39,36 @@ int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
MPI_Datatype recvtype, int root, MPI_Comm comm)
{
int i, size, err;
MEMCHECKER(
memchecker_datatype(sendtype);
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
int rank;
ptrdiff_t ext;
size = ompi_comm_size(comm);
rank = ompi_comm_rank(comm);
ompi_ddt_type_extent(recvtype, &ext);
memchecker_comm(comm);
if (ompi_comm_rank(comm) == root || MPI_ROOT == root) {
memchecker_datatype(recvtype);
/* check whether each receive buffer is addressable/defined(MPI_IN_PLACE). */
if(MPI_IN_PLACE == sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined,
recvbuf+displs[rank]*ext,
recvcounts[rank], recvtype );
}
for (i = 0; i < size; i++) {
memchecker_call(&opal_memchecker_base_isaddressable,
recvbuf+displs[i]*ext,
recvcounts[i], recvtype);
}
}
/* check whether send buffer is defined on all processses. */
if (MPI_PROC_NULL != root && MPI_IN_PLACE != sendbuf ) {
memchecker_datatype(sendtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -41,7 +41,7 @@ int MPI_Recv(void *buf, int count, MPI_Datatype type, int source,
MEMCHECKER(
memchecker_datatype(type);
memchecker_call(&opal_memchecker_base_isaddressible, buf, count, type);
memchecker_call(&opal_memchecker_base_isaddressable, buf, count, type);
memchecker_comm(comm);
);

Просмотреть файл

@ -41,7 +41,7 @@ int MPI_Recv_init(void *buf, int count, MPI_Datatype type, int source,
MEMCHECKER(
memchecker_datatype(type);
memchecker_call(&opal_memchecker_base_isaddressible, buf, count, type);
memchecker_call(&opal_memchecker_base_isaddressable, buf, count, type);
memchecker_comm(comm);
);

Просмотреть файл

@ -42,8 +42,21 @@ int MPI_Reduce(void *sendbuf, void *recvbuf, int count,
MEMCHECKER(
memchecker_datatype(datatype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
memchecker_comm(comm);
/* check whether root's receive buffer is addressable. */
if( ompi_comm_rank(comm) == root || MPI_ROOT == root ) {
if (MPI_IN_PLACE == sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined, recvbuf, count, datatype);
} else {
memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, count, datatype);
}
}
/* check whether send buffer is defined on all processes. */
if (MPI_PROC_NULL != root && MPI_IN_PLACE != sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -41,9 +41,30 @@ int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
int i, err, size, count;
MEMCHECKER(
memchecker_datatype(datatype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
int rank;
size = ompi_comm_size(comm);
rank = ompi_comm_rank(comm);
for (count = i = 0; i < size; ++i) {
if (0 == recvcounts[i]) {
++count;
}
}
memchecker_comm(comm);
memchecker_datatype(datatype);
/* check receive buffer of current proccess, whether it's addressable. */
memchecker_call(&opal_memchecker_base_isaddressable, recvbuf,
recvcounts[rank], datatype);
/* check whether the actual send buffer is defined. */
if(MPI_IN_PLACE == sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined, recvbuf, count, datatype);
} else {
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -42,8 +42,12 @@ int MPI_Scan(void *sendbuf, void *recvbuf, int count,
MEMCHECKER(
memchecker_datatype(datatype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
memchecker_comm(comm);
if (MPI_IN_PLACE != sendbuf) {
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
} else {
memchecker_call(&opal_memchecker_base_isdefined, recvbuf, count, datatype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -44,10 +44,17 @@ int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
int err;
MEMCHECKER(
memchecker_datatype(sendtype);
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
memchecker_comm(comm);
if (ompi_comm_rank(comm) == root || MPI_ROOT == root) {
memchecker_datatype(sendtype);
/* check whether root's send buffer is defined. */
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
}
/* check whether the receive buffer is addressable. */
if (MPI_PROC_NULL != root && MPI_IN_PLACE != recvbuf) {
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, recvcount, recvtype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -41,10 +41,26 @@ int MPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
int i, size, err;
MEMCHECKER(
memchecker_datatype(sendtype);
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isdefined, sendbuf, *sendcounts, sendtype);
ptrdiff_t ext;
size = ompi_comm_size(comm);
ompi_ddt_type_extent(recvtype, &ext);
memchecker_comm(comm);
if (ompi_comm_rank(comm) == root || MPI_ROOT == root) {
memchecker_datatype(sendtype);
/* check each send buffer, whether they are defined. */
for (i = 0; i < size; i++) {
memchecker_call(&opal_memchecker_base_isdefined,
sendbuf+displs[i]*ext,
sendcounts[i], sendtype);
}
}
/* check whether the receive buffer is addressable */
if (MPI_PROC_NULL != root && MPI_IN_PLACE != recvbuf) {
memchecker_datatype(recvtype);
memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, recvcount, recvtype);
}
);
if (MPI_PARAM_CHECK) {

Просмотреть файл

@ -120,11 +120,11 @@ OPAL_DECLSPEC int opal_memchecker_base_runindebugger(void);
* @retval OPAL_SUCCESS upon success.
*
* This function calls the selected memchecker, whether
* every Byte of this memory region is addressible
* every Byte of this memory region is addressable
*/
OPAL_DECLSPEC int opal_memchecker_base_isaddressible(void * p, size_t len);
OPAL_DECLSPEC int opal_memchecker_base_isaddressable(void * p, size_t len);
#if OMPI_WANT_MEMCHECKER == 0
#define opal_memchecker_base_isaddressible(p, len) 0
#define opal_memchecker_base_isaddressable(p, len) 0
#endif
@ -193,7 +193,7 @@ OPAL_DECLSPEC int opal_memchecker_base_mem_defined(void * p, size_t len);
#endif
/**
* Set a memory region to defined only if the region is addressible
* Set a memory region to defined only if the region is addressable
*
* @param p Pointer to the memory region
* @param len Length of the memory region
@ -202,11 +202,11 @@ OPAL_DECLSPEC int opal_memchecker_base_mem_defined(void * p, size_t len);
*
* This function calls the selected memchecker, to set
* every Byte of this memory region to contain valid, initialized data,
* but only, if the memory region is addressible.
* but only, if the memory region is addressable.
*/
OPAL_DECLSPEC int opal_memchecker_base_mem_defined_if_addressible(void * p, size_t len);
OPAL_DECLSPEC int opal_memchecker_base_mem_defined_if_addressable(void * p, size_t len);
#if OMPI_WANT_MEMCHECKER == 0
#define opal_memchecker_base_mem_defined_if_addressible(p, len)
#define opal_memchecker_base_mem_defined_if_addressable(p, len)
#endif
/**

Просмотреть файл

@ -23,9 +23,9 @@ int opal_memchecker_base_runindebugger(void)
return opal_memchecker_base_module->runindebugger();
}
int opal_memchecker_base_isaddressible(void * p, size_t len)
int opal_memchecker_base_isaddressable(void * p, size_t len)
{
return opal_memchecker_base_module->isaddressible(p, len);
return opal_memchecker_base_module->isaddressable(p, len);
}
@ -53,9 +53,9 @@ int opal_memchecker_base_mem_defined(void * p, size_t len)
}
int opal_memchecker_base_mem_defined_if_addressible(void * p, size_t len)
int opal_memchecker_base_mem_defined_if_addressable(void * p, size_t len)
{
return opal_memchecker_base_module->mem_defined_if_addressible(p, len);
return opal_memchecker_base_module->mem_defined_if_addressable(p, len);
}

Просмотреть файл

@ -51,9 +51,9 @@ typedef int (*opal_memchecker_base_module_init_1_0_0_fn_t)(void);
typedef int (*opal_memchecker_base_module_runindebugger_fn_t)(void);
/**
* Module function to check, whether memory region is addressible
* Module function to check, whether memory region is addressable
*/
typedef int (*opal_memchecker_base_module_isaddressible_fn_t)(void * p, size_t len);
typedef int (*opal_memchecker_base_module_isaddressable_fn_t)(void * p, size_t len);
/**
* Module function to check, whether memory region is defined
@ -76,9 +76,9 @@ typedef int (*opal_memchecker_base_module_mem_undefined_fn_t)(void * p, size_t l
typedef int (*opal_memchecker_base_module_mem_defined_fn_t)(void * p, size_t len);
/**
* Module function to set memory region to defined, but only if addressible
* Module function to set memory region to defined, but only if addressable
*/
typedef int (*opal_memchecker_base_module_mem_defined_if_addressible_fn_t)(void * p, size_t len);
typedef int (*opal_memchecker_base_module_mem_defined_if_addressable_fn_t)(void * p, size_t len);
/**
* Module function name a specific memory region
@ -133,8 +133,8 @@ struct opal_memchecker_base_module_1_0_0_t {
/** Module function to check, whether we are executed by memory debugger */
opal_memchecker_base_module_runindebugger_fn_t runindebugger;
/** Module function to check, whether memory region is addressible */
opal_memchecker_base_module_isaddressible_fn_t isaddressible;
/** Module function to check, whether memory region is addressable */
opal_memchecker_base_module_isaddressable_fn_t isaddressable;
/** Module function to check, whether memory region is defined */
opal_memchecker_base_module_isdefined_fn_t isdefined;
@ -148,8 +148,8 @@ struct opal_memchecker_base_module_1_0_0_t {
/** Module function to set memory region to defined */
opal_memchecker_base_module_mem_defined_fn_t mem_defined;
/** Module function to set memory region to defined, but only if addressible */
opal_memchecker_base_module_mem_defined_if_addressible_fn_t mem_defined_if_addressible;
/** Module function to set memory region to defined, but only if addressable */
opal_memchecker_base_module_mem_defined_if_addressable_fn_t mem_defined_if_addressable;
/** Module function name a specific memory region */
opal_memchecker_base_module_create_block_fn_t create_block;

Просмотреть файл

@ -34,12 +34,12 @@
*/
static int valgrind_module_init(void);
static int valgrind_module_runindebugger(void);
static int valgrind_module_isaddressible(void * p, size_t len);
static int valgrind_module_isaddressable(void * p, size_t len);
static int valgrind_module_isdefined(void * p, size_t len);
static int valgrind_module_mem_noaccess(void * p, size_t len);
static int valgrind_module_mem_undefined(void * p, size_t len);
static int valgrind_module_mem_defined(void * p, size_t len);
static int valgrind_module_mem_defined_if_addressible(void * p, size_t len);
static int valgrind_module_mem_defined_if_addressable(void * p, size_t len);
static int valgrind_module_create_block(void * p, size_t len, char * description);
static int valgrind_module_discard_block(void * p); /* Here, we need to do some mapping for valgrind */
static int valgrind_module_leakcheck(void);
@ -57,12 +57,12 @@ static const opal_memchecker_base_module_1_0_0_t loc_module = {
/* Module function pointers */
valgrind_module_runindebugger,
valgrind_module_isaddressible,
valgrind_module_isaddressable,
valgrind_module_isdefined,
valgrind_module_mem_noaccess,
valgrind_module_mem_undefined,
valgrind_module_mem_defined,
valgrind_module_mem_defined_if_addressible,
valgrind_module_mem_defined_if_addressable,
valgrind_module_create_block,
valgrind_module_discard_block,
valgrind_module_leakcheck
@ -96,7 +96,7 @@ static int valgrind_module_runindebugger(void)
}
static int valgrind_module_isaddressible(void * p, size_t len)
static int valgrind_module_isaddressable(void * p, size_t len)
{
if (len > 0) {
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(p, len);
@ -146,7 +146,7 @@ static int valgrind_module_mem_defined(void * p, size_t len)
}
static int valgrind_module_mem_defined_if_addressible(void * p, size_t len)
static int valgrind_module_mem_defined_if_addressable(void * p, size_t len)
{
if (len > 0) {
VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(p, len);