Example #1
0
vector<double> Configuration::GetFloatArray(string const & field) const
{
  vector<string> param_tokens = GetStrArray(field);
  vector<double> values;
  assert(values.empty());
  for(size_t i = 0; i < param_tokens.size(); ++i) {
    char const * const token = param_tokens[i].c_str();
    double const value = atof(token);
    values.push_back(value);
    assert(values[i] == value);
  }
  assert(values.size() == param_tokens.size());
  return values;
}
Example #2
0
void str_cli(FILE *fp, int sockfd) {
	printf("In str_cli\n");
	char sendline[BUFFSIZE], recvline[BUFFSIZE];
	int len = 0;
	int maxfdp1;
	fd_set rset;
	FD_ZERO(&rset);

	if (fileno(fp) > sockfd) {
		maxfdp1 = fileno(fp) + 1;
	} else {
		maxfdp1 = sockfd + 1;
	}

	while (1) {
		FD_ZERO(&rset);
		FD_SET(fileno(fp), &rset);
		FD_SET(sockfd, &rset);

		select(maxfdp1, &rset, NULL, NULL, NULL);
		if (errno == EINTR) {
			continue;
		}

		if (FD_ISSET(sockfd, &rset)) {
			if ((len = recv(sockfd, recvline, BUFFSIZE, 0)) == 0) {
				printf("str_cli:server terminated prematurely\n");
				return;
			}

			if (recvline[0] == '@') //如果读取到线程相关信息,则记录下来,进行过滤信息
			{
//				printf("监控序列数据接收\n");
				char output[10][200];
				memset(output, 0, sizeof(output));
				GetStrArray(recvline, ',', output); //将收到的信息以逗号分割开来

				//将对应的信息从字符数组转化为unsigned long
				unsigned long curPthreadId = charToUnsignedLong(output[0]);
				unsigned long curExeVri = charToUnsignedLong(output[1]);
				unsigned long curLineNum = charToUnsignedLong(output[2]);
				unsigned long curType = charToUnsignedLong(output[3]);
				unsigned long curMutexAddr = charToUnsignedLong(output[4]);
				unsigned long curLockOrder = charToUnsignedLong(output[5]);

				if (curType == 2) //加锁信息
				{
					if (pthHead == NULL) //链表为空,不存在任何节点,新建节点,并将head和cur指向第一个节点
					{
						pthHead = pthCur = (struct PthreadShowInfo*) malloc(
								sizeof(struct PthreadShowInfo));
						memset(pthCur, 0, sizeof(struct PthreadShowInfo));

						pthCur->pthreadId = curPthreadId;
						pthCur->apply = NULL;
						pthCur->next = NULL;

						if (curLockOrder == 0) //lockOrder为0表示该锁是此线程正在申请的锁
						{
							pthCur->requestExeVri = curExeVri;
							pthCur->requestLinenum = curLineNum;
							pthCur->requestLock = curMutexAddr;
							strcpy(pthCur->requestName,output[7]);
							strcpy(pthCur->requestMutexName,output[8]);
							pthCur->heldLock = NULL;
						} else if (curLockOrder > 0) //lockOrder大于0表示该锁是此线程已经拥有的锁
						{
							pthCur->requestExeVri = 0;
							pthCur->requestLinenum = 0;
							pthCur->requestLock = 0;
							strcpy(pthCur->requestName,"");

							struct HeldLockInfo* heldlockmed =
									(struct HeldLockInfo*) malloc(
											sizeof(struct HeldLockInfo));
							memset(heldlockmed, 0, sizeof(struct HeldLockInfo));
							heldlockmed->exeVri = curExeVri;
							heldlockmed->linenum = curLineNum;
							heldlockmed->lockOrder = curLockOrder;
							heldlockmed->mutexAddr = curMutexAddr;
							strcpy(heldlockmed->fileName,output[7]);
							strcpy(heldlockmed->mutexName,output[8]);
							heldlockmed->next = NULL;
							pthCur->heldLock = heldlockmed;
						}
					} else //链表中已经存在节点,再判断是否存在该线程号对应的节点
					{
						struct PthreadShowInfo* pthTemp = pthHead;
						int ifCurPthreadExist = 0;
						while (pthTemp != NULL) //循环遍历链表,看其中是否存在该线程号的节点
						{
							if (pthTemp->pthreadId == curPthreadId) {
								ifCurPthreadExist = 1;
								break;
							}
							pthTemp = pthTemp->next;
						}

						if (ifCurPthreadExist == 1) //说明在链表中已经存在此线程号的节点
						{
							if (curLockOrder == 0) //lockOrder为0表示该锁是此线程正在申请的锁
							{
								pthTemp->requestExeVri = curExeVri;
								pthTemp->requestLinenum = curLineNum;
								pthTemp->requestLock = curMutexAddr;
								strcpy(pthTemp->requestName,output[7]);
								strcpy(pthTemp->requestMutexName,output[8]);
							} else if (curLockOrder > 0) //lockOrder大于0表示该锁是此线程已经拥有的锁
							{
								//新建结点,将相关信息填入节点中
								struct HeldLockInfo* heldlockmed =
										(struct HeldLockInfo*) malloc(
												sizeof(struct HeldLockInfo));
								memset(heldlockmed, 0,
										sizeof(struct HeldLockInfo));
								heldlockmed->exeVri = curExeVri;
								heldlockmed->linenum = curLineNum;
								heldlockmed->lockOrder = curLockOrder;
								heldlockmed->mutexAddr = curMutexAddr;
								strcpy(heldlockmed->fileName,output[7]);
								strcpy(heldlockmed->mutexName,output[8]);
								heldlockmed->next = NULL;

								if (pthTemp->heldLock != NULL) //不为空说明该线程还有其他已拥有的锁已经在链表中存在
								{
									struct HeldLockInfo* heldlockcur =
											pthTemp->heldLock;
									struct HeldLockInfo* heldlockpre =
											heldlockcur;

									while (heldlockcur != NULL) //链表不为空,则根据lockOrder大小将其插入链表中
									{
										if (heldlockcur->lockOrder
												< curLockOrder) {
											heldlockpre = heldlockcur;
											heldlockcur = heldlockcur->next;
										} else {
											heldlockmed->next = heldlockcur;
											heldlockpre->next = heldlockmed;
											break;
										}
									}
									if ((heldlockcur == NULL)
											&& (heldlockpre->lockOrder
													< curLockOrder)) //此情况下,将新节点插入到链表尾部
									{
										heldlockpre->next = heldlockmed;
									}
								} else //链表为空,则将该节点直接插入链表中即可
								{
									pthTemp->heldLock = heldlockmed;
								}
							}
						} else //说明在链表中不存在此线程号的节点,需要新建一个
						{
							struct PthreadShowInfo *med =
									(struct PthreadShowInfo*) malloc(
											sizeof(struct PthreadShowInfo));
							memset(med, 0, sizeof(struct PthreadShowInfo));
							med->pthreadId = curPthreadId;
							med->apply = NULL;
							//使得pthCur一直保持指向链表的最后一个节点
							pthCur->next = med;
							med->next = NULL;
							pthCur = med;

							if (curLockOrder == 0) //lockOrder为0表示该锁是此线程正在申请的锁
							{
								med->requestExeVri = curExeVri;
								med->requestLinenum = curLineNum;
								med->requestLock = curMutexAddr;
								strcpy(med->requestName,output[7]);
								strcpy(med->requestMutexName,output[8]);
								med->heldLock = NULL;
							} else if (curLockOrder > 0) //lockOrder大于0表示该锁是此线程已经拥有的锁
							{
								//新建结点,将相关信息填入节点中
								struct HeldLockInfo* heldlockmed =
										(struct HeldLockInfo*) malloc(
												sizeof(struct HeldLockInfo));
								memset(heldlockmed, 0,
										sizeof(struct HeldLockInfo));
								heldlockmed->exeVri = curExeVri;
								heldlockmed->linenum = curLineNum;
								heldlockmed->lockOrder = curLockOrder;
								heldlockmed->mutexAddr = curMutexAddr;
								strcpy(heldlockmed->fileName,output[7]);
								strcpy(heldlockmed->mutexName,output[8]);
								heldlockmed->next = NULL;
								med->heldLock = heldlockmed;
							}
						}
					}
				} else if (curType == 3) //去除链表中线程已经释放的锁的信息
				{
					struct PthreadShowInfo* pthTemp = pthHead;

					while (pthTemp != NULL) {
						if (pthTemp->pthreadId == curPthreadId) //找到进行加锁操作的线程在链表中的位置
						{
							struct HeldLockInfo *cur = pthTemp->heldLock;
							struct HeldLockInfo *pre = cur;

							while (cur != NULL)
							{
								if (cur->mutexAddr == curMutexAddr) //在线程拥有锁的链表中找到该锁,并释放
								{
									if(pre == cur) //heldLock链表中只有一个加锁节点
										pthTemp->heldLock = NULL;
									else	//heldLock链表中存在多个加锁节点
										pre->next = cur->next;

									free(cur);
									break;

								} else {
									pre = cur;
									cur = cur->next;
								}
							}

							break;
						}
						pthTemp = pthTemp->next;
					}
				}
				else if (curType == 1)
				{
					++totalThreadNum;
				}
			}
			else if((recvline[0] == '&'))		//合成序列数据接收
			{
//				printf("合成序列数据接收\n");
				char output[10][200];
				memset(output, 0, sizeof(output));
				GetStrArray(recvline, ',', output); //将收到的信息以逗号分割开来

				//将对应的信息从字符数组转化为unsigned long
				int curPthreadId = charToUnsignedLong(output[0]);
				unsigned long curExeVri = charToUnsignedLong(output[1]);
				int curLineNum = charToUnsignedLong(output[2]);
				int curType = charToUnsignedLong(output[3]);
				unsigned long curMutexAddr = charToUnsignedLong(output[4]);
				int curLockOrder = charToUnsignedLong(output[5]);
				int curNewThreadId = charToUnsignedLong(output[6]);

				if(exeHead == NULL)
				{
					exeHead = exeCur = (struct ExecutePath*)malloc(sizeof(struct ExecutePath));
					memset(exeCur,0,sizeof(struct ExecutePath));
					exeCur->pthreadId = curPthreadId;
					exeCur->type = curType;
					exeCur->lineNum = curLineNum;
					exeCur->lockOrder = curLockOrder;
					exeCur->mutexAddr = curMutexAddr;
					exeCur->newPthreadId = curNewThreadId;
					strcpy(exeCur->filename,output[7]);
					strcpy(exeCur->mutexname,output[8]);
					exeCur->next = NULL;
				}else{
					struct ExecutePath *temp = (struct ExecutePath*)malloc(sizeof(struct ExecutePath));
					memset(temp, 0, sizeof(struct ExecutePath));
					temp->pthreadId = curPthreadId;
					temp->type = curType;
					temp->lineNum = curLineNum;
					temp->lockOrder = curLockOrder;
					temp->mutexAddr = curMutexAddr;
					temp->newPthreadId = curNewThreadId;
					strcpy(temp->filename,output[7]);
					strcpy(temp->mutexname,output[8]);
					temp->next = NULL;
					exeCur->next = temp;
					exeCur = temp;
				}
			}
			else if((recvline[0] == '*'))
			{
				char output[10][200];
				memset(output, 0, sizeof(output));
				GetStrArray(recvline, ',', output); //将收到的信息以逗号分割开来

				char fileLineStr[5][200];
				memset(fileLineStr, 0, sizeof(fileLineStr));
				GetStrArray(recvline, '^', fileLineStr); //将收到的信息以逗号分割开来

				//将对应的信息从字符数组转化为unsigned long
				int curPthreadId = charToUnsignedLong(output[0]);
				unsigned long curExeVri = charToUnsignedLong(output[1]);
				int curLineNum = charToUnsignedLong(output[2]);
				int curType = charToUnsignedLong(output[3]);
				unsigned long curMutexAddr = charToUnsignedLong(output[4]);
				int curLockOrder = charToUnsignedLong(output[5]);
				int curNewThreadId = charToUnsignedLong(output[6]);

				if (reHead == NULL) {
					reHead = reCur = (struct ExecutePath*) malloc(sizeof(struct ExecutePath));
					memset(reCur, 0, sizeof(struct ExecutePath));
					reCur->pthreadId = curPthreadId;
					reCur->type = curType;
					reCur->lineNum = curLineNum;
					reCur->lockOrder = curLockOrder;
					reCur->mutexAddr = curMutexAddr;
					reCur->newPthreadId = curNewThreadId;
					strcpy(reCur->filename,output[7]);
					strcpy(reCur->mutexname,output[8]);
					strcpy(reCur->mutexstr,fileLineStr[1]);
					reCur->next = NULL;
				} else {
					struct ExecutePath *temp = (struct ExecutePath*) malloc(sizeof(struct ExecutePath));
					memset(temp, 0, sizeof(struct ExecutePath));
					temp->pthreadId = curPthreadId;
					temp->type = curType;
					temp->lineNum = curLineNum;
					temp->lockOrder = curLockOrder;
					temp->mutexAddr = curMutexAddr;
					temp->newPthreadId = curNewThreadId;
					strcpy(temp->filename, output[7]);
					strcpy(temp->mutexname, output[8]);
					strcpy(temp->mutexstr,fileLineStr[1]);
					temp->next = NULL;
					reCur->next = temp;
					reCur = temp;
				}
			}
			else if((recvline[0] == '?'))
			{
				int i = 0;
				while(recvline[i] != '\0')
				{
					recvline[i] = recvline[i+1];
					++i;
				}
				strcpy(deadlockSet[deadlockNum],recvline);
				++deadlockNum;
			}
			else if (recvline[0] == '$') //读到此标志,表示已经读取结束,则发送结束标志信号
			{
//				printf("所有数据接收完毕\n");
				getMinDeadlockSet(pthHead);

				char flagFilePath[200];
				strcpy(flagFilePath,filePath);
				strcat(flagFilePath,"end_flag.txt");

				FILE * fp;
				fp = fopen(flagFilePath, "w+");
				if(fp == NULL)
				{
					printf("打开end_flag.txt失败!\n");
					return ;
				}

				if(deadlockFlag == 0) //没有发生死锁
				{
					if(recvline[1] == 'Y')	//没有发生死锁,但是程序存在死锁的可能
					{
						writeResult3(deadlockSet);
						writeResult2(exeHead);
						fprintf(fp, "%s\n", "$Deadlock exist$");
					}
					else if(recvline[1] == 'N')	//没有发生死锁,程序也不可能发生死锁
					{
						fprintf(fp, "%s\n", "$Deadlock not exist$");

						//向文件中写入总的线程数量
						char threadFilePath[200];
						strcpy(threadFilePath,filePath);
						strcat(threadFilePath,"totalNum.txt");

						FILE *numFP;
						numFP = fopen(threadFilePath, "w+");
						if(numFP == NULL)
						{
							printf("打开totalNum.txt失败\n");
							return ;
						}
						fprintf(numFP, "%d\n", totalThreadNum);
						fclose(numFP);
					}
					printf("No deadlock\n");
				}else{
					if(recvline[1] == 'D')
					{
						if (deadlockFlag == 1) //发生了死锁
							fprintf(fp, "%s\n", "$Deadlock$");
						else if (deadlockFlag == 2) //发生了自选锁
							fprintf(fp, "%s\n", "$Selflock$");
						writeResult(finalHead);
						writeResult4(finalHead);
					}
				}
				fclose(fp);
			}
			else if (recvline[0] == 'w') //welcome to server
				printf("%s", recvline);
			else if(recvline[0] == 'r')
			{
				writeResult2(reHead);

				char flagFilePath[200];
				strcpy(flagFilePath,filePath);
				strcat(flagFilePath,"end_flag.txt");

				FILE * fp;
				fp = fopen(flagFilePath, "w+");
				if(fp == NULL)
				{
					printf("打开end_flag.txt失败!\n");
					return;
				}
				fprintf(fp,"%s\n","$Replay over$");
				fclose(fp);

				printf("%s", recvline);
			}
			else if(recvline[0] == 'q' || recvline[0] == 'Q')
				return ;
		}

		if (FD_ISSET(fileno(fp), &rset)) {
			if (fgets(sendline, BUFFSIZE, fp) == NULL)
				break;
			len = send(sockfd, sendline, BUFFSIZE, 0);

			if (sendline[0] == 'q' || sendline[0] == 'Q') {
				printf("str_cli:server terminated prematurely\n");
				return;
			}
		}
	}
}