rem: "readlock, readunlock, writelock, writeunlock");
add: "readlock, readunlock, writelock, " "writeunlock", NULL);
context: NsTclRWLockCmd(ClientData data, Tcl_Interp *interp, int argc, char **argv){    Ns_RWLock *rwlockPtr;    if (argc < 2) {	Tcl_AppendResult(interp, "wrong # args: should be \"",			 argv[0], " command ...\"", NULL);	return TCL_ERROR;    }        if (STREQ(argv[1], "create")) {	rwlockPtr = ns_malloc(sizeof(Ns_RWLock));	Ns_RWLockInit(rwlockPtr);	SetObj(interp, 'r', rwlockPtr);    } else {	if (argc < 3) {	    Tcl_AppendResult(interp, "wrong # args: should be \"",			     argv[0], " ", argv[1], " rwlock ?...?\"", NULL);	    return TCL_ERROR;	} else if (GetObj(interp, 'r', argv[2], 				      (void**) &rwlockPtr) != TCL_OK) {	    return TCL_ERROR;	}	if (STREQ(argv[1], "destroy")) {	    Ns_RWLockDestroy(rwlockPtr);	    ns_free(rwlockPtr);	} else if (STREQ(argv[1], "readlock")) {	    Ns_RWLockRdLock(rwlockPtr);	} else if (STREQ(argv[1], "readunlock")) {	    Ns_RWLockUnlock(rwlockPtr);	} else if (STREQ(argv[1], "writelock")) {	    Ns_RWLockWrLock(rwlockPtr);	} else if (STREQ(argv[1], "writeunlock")) {	    Ns_RWLockUnlock(rwlockPtr);	} else if (STREQ(argv[1], "unlock")) {	    Ns_RWLockUnlock(rwlockPtr);	} else {	    Tcl_AppendResult(interp, "unknown command \"",			     argv[1], "\":should be create, destroy, "			     "readlock, readunlock, writelock, writeunlock");	    return TCL_ERROR;	}    }    return TCL_OK;}