This library can be added to a C project to generate a ShiViz-compatible vector-clock timestamped log of events in a concurrent or distributed system. CVector is written in ANSI C11.
- cvec/ : Contains the Library and all its dependencies
- example/ : Contains examples which can be instrumented with CVector
CVector has the following dependencies:
VClock - A vector clock library written in C.
src/vclock/vclock.h
MPack - A MessagePack implementation.
src/mpack/mpack.h
To use CVector simply include src/cvec.h.
You can compile your project by including the following header files:
src/vclock/cvec.h src/vclock/vclock.h src/mpack/mpack.h
Or by generating the libcvec library via this command:
make liband then compiling your program by including src/libcvec.a
gcc -o myApp src/libcvec.astruct vcLog *initCVector(char *pid, char *logName);
int writeLogMsg(struct vcLog *vcInfo, char *logMsg);
int loglocalEvent(struct vcLog *vcInfo, char *logMsg);
char *prepareSend(struct vcLog *vcInfo, char *logMsg, char *packetContent, int *encodeLen);
char *unpackReceive(struct vcLog *vcInfo, char *logMsg, char *encodedBuffer, int bufLen);
void EnableLogging (struct vcLog *vcInfo)
void DisableLogging (struct vcLog *vcInfo)
structvcLog {
charpid[VC_ID_LENGTH]; // Fixed to VC_ID_LENGTH defined in vclock.h.structvectorClock*vc; // The local vector clock map.charlogName[FILE_MAX]; // Name of the CVector log file to write to.intprintonscreen; // Print all logging operations to screen.intlogging; // Enable logging.
}This is the basic vcLog structure used in any CVector application. It contains the thread-local vector clock and process as well as information about the logging procedure and file name.
structvcLog*initCVector(char*pid, char*logName)Initialises and returns a new vcLog structure. This vcLog structure contains the configuration of the current vector thread as well as the vector clock map and process id. This structure is the basis of any further operation in CVector. Any log files with the same name as "logName" will be overwritten. "pid" should be unique in the current distributed system.
char*prepareSend(structvcLog*vcInfo, char*logMsg, char*packetContent, int*encodeLen)Decodes a CVector buffer, updates the local vector clock, and returns the decoded data. This function takes a MessagePack buffer and extracts the vector clock as well as data. It increments the local vector clock, merges the unpacked clock with its own and returns a character representation of the data. In addition, prepareSend writes a custom defined message to the main CVector log.
char*unpackReceive(structvcLog*vcInfo, char*logMsg, char*encodedBuffer, intbufLen)Decodes a CVector buffer, updates the local vector clock, and returns the decoded data. This function takes a MessagePack buffer and extracts the vector clock as well as data. It increments the local vector clock, merges the unpacked clock with its own and returns a character representation of the data. In addition, prepareSend writes a custom defined message to the main CVector log.
intlogLocalEvent(structvcLog*vcInfo, char*logMsg)Records a local event and increments the vector clock contained in "vcInfo". Also appends a message in the log file defined in the vcInfo structure.
intwriteLogMsg(structvcLog*vcInfo, char*logMsg)Appends a message in the log file defined in the vcLog vcInfo structure.
voidenableLogging(structvcLog*vcInfo);Enables the logging mechanism of CVector. Logging is turned on by default.
This is a cosmetic function. Setting vcInfo->logging to 1 fulfils the same purpose.
voiddisableLogging(structvcLog*vcInfo);Disables the logging mechanism of CVector. Logging is turned on by default.
This is a cosmetic function. Setting vcInfo->logging to 0 fulfils the same purpose.
The following is a basic example of how this library can be used:
#include"../src/cvec.h"intmain (){
structvcLog*vcInfo=initCVector("MyProcess","basiclog");
//Prepare and send a Messageintsize;
charsendingMessage[50];
strcpy(sendingMessage, "ExampleMessage");
printf("We are packing this message: %s\n", sendingMessage);
char*resultBuffer=prepareSend(vcInfo, "Sending Message", sendingMessage, &size);
//Unpack the message againchar*receivedMessage=unpackReceive(vcInfo, "Receiving Message", resultBuffer, size);
printf("We received this message: %s\n", receivedMessage);
//Can be called at any point logLocalEvent(vcInfo, "Example Complete");
//No further events will be written to log filedisableLogging(vcInfo);
logLocalEvent(vcInfo, "This will not be logged.");
}This produces the log "basiclog.shiviz" :
MyProcess {"MyProcess":1}
Initialization Complete
MyProcess {"MyProcess":2}
Sending Message
MyProcess {"MyProcess":3}
Receiving Message
MyProcess {"MyProcess":4}
Example Complete
An executable example of a similar program can be found in example/client_server.c