Rearrange Matrix using threads - c

I`m trying to do this program, that taking matrix 4X4, and then creating 4 threads, and in parallel inserting the 4X4 matrix into array of 16 integer, sorting like this. odd number will go to odd index, and even number to even index in the array.
2 1 10 9 4 ec`
for example
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
will looks something like this:
The arranged array:
2 1 10 9 4 3 12 11 6 5 14 13 8 7 16 15
Num 2 was found by thread 0
Num 1 was found by thread 2
Num 10 was found by thread 1
Num 9 was found by thread 3
Num 4 was found by thread 0
Num 3 was found by thread 2
Num 12 was found by thread 1
Num 11 was found by thread 3
Num 6 was found by thread 0
Num 5 was found by thread 2
Num 14 was found by thread 1
Num 13 was found by thread 3
Num 8 was found by thread 0
Num 7 was found by thread 2
Num 16 was found by thread 1
Num 15 was found by thread 3
Now I came up with this code, but for some reason I'm not using all the threads like in the sample. I mean in the sample there is thread 0 then 2 then 1 then 3 etc. very mixed. I'm from other hand getting thread 0, thread 0, thread 0, 3, 3 ,0,0 etc.
How can I fix this?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define MAX 4
#define MAX_THREAD 4
int i = 0;
int newmatrix[16];
int oldmatrix[MAX][MAX] =
{1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16};
int isUsed(int num)
{
for (int p = 0; p < 16; p++)
if (newmatrix[p] == num)
return 0;
return 1;
}
void *printHello(void *threadid)
{
int j, k;
long tid;
tid = (long)threadid;
while (i < 16)
{
sleep(0.01);
for (j = 0; j < 4; j++)
{
for (k = 0; k < 4; k++)
{
if (oldmatrix[j][k] % 2 == 0 && isUsed(oldmatrix[j][k]))
{
newmatrix[i] = oldmatrix[j][k];
printf("Num %d was found by thread %ld\n", oldmatrix[j][k], tid);
i++;
}
else if (isUsed(oldmatrix[j][k]))
{
newmatrix[i] = oldmatrix[j][k];
printf("Num %d was found by thread %ld\n", oldmatrix[j][k], tid);
i++;
}
}
}
}
if (tid == 1)
{
sleep(2);
printf("Hello There! thread %ld \n\n", tid);
for (int p = 0; p < 16; p++)
printf("%d ", newmatrix[p]);
}
pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
pthread_t threads[MAX_THREAD];
int rc;
long t;
for (t = 0; t < MAX_THREAD; t++)
{
rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
if (rc)
{
printf("ERORR; return code from pthread_create() is %d\n", rc);
exit(EXIT_FAILURE);
}
}
pthread_exit(NULL);
}

Related

Why 2 is not smaller than 10 on Codeblocks?

I just worked to my final exam with simple codes; when I try to sorting strings, I face annoying error. Why 2 is not smaller than 10 on my CodeBlocks IDE but is smaller than 10 on real and onlinegdb.com?
This is the annoying code:
#include <string.h>
#include <stdio.h>
#define STR_SIZ 20
int main()
{
char strArr[][STR_SIZ] = {"abc", "hdas", "sdfasf", "kakldf", "caksl", "casd", "keam", "cznjcx", "mnxzv", "jkalkds"};
char minStr[STR_SIZ];
strcpy(minStr, strArr[0]);
int N = sizeof(strArr)/sizeof(minStr);
// int N = 10;
for(int x = 0; x < N-1; x++)
{
printf("%d", x);
strcpy(minStr,strArr[x]);
int j;
for(j=1+x; j < 10; j++)
{
printf("%4d\n", j);
int cmp = strcmp(strArr[j], minStr);
if(cmp < 0)
strcpy(minStr,strArr[j]);
}
char temp[STR_SIZ];
strcpy(temp,strArr[x]);
strcpy(strArr[x], minStr);
strcpy(strArr[j], temp);
}
return 0;
}
Output on onlinegdb.com:
0 1
2
3
4
5
6
7
8
9
1 2
3
4
5
6
7
8
9
2 3
4
5
6
7
8
9
3 4
5
6
7
8
9
4 5
6
7
8
9
5 6
7
8
9
6 7
8
9
7 8
9
8 9
Output on CodeBlocks:
0 1
2
3
4
5
6
7
8
9
1 2
3
4
5
6
7
8
9
2
PS: I just have used Codeblock in the morning and it was okey with executing.
strArr has 10 elements. At the end of your loop, you call strcpy(strArr[j], temp);. This will write to strArr[10], which is out of bounds and will overwrite some unknown memory. Anything can happen after that.
You should save the j value when you copy a string into minStr.
FYI, your code above prints this as your final string order with onlinegdb:
abc
caksl
caksl
caksl
caksl
casd
cznjcx
cznjcx
jkalkds
jkalkds
So I think you have other problems as well.
try this
#include <string.h>
#include <stdio.h>
#define STR_SIZ 20
int main()
{
char strArr[][STR_SIZ] = {"abc", "hdas", "sdfasf", "kakldf", "caksl", "casd", "keam", "cznjcx", "mnxzv", "jkalkds"};
strcpy(minStr, strArr[0]);
// Calculate the number of elements this way.
const int N = sizeof(strArr)/sizeof(strArr[0]);
// int N = 10;
for(int x = 0; x < N-1; x++)
{
printf("%d", x);
int j;
for(j=1+x; j < N; j++) // Use N here too!
{
printf("%4d\n", j);
int cmp = strcmp(strArr[j], strArr[x]);
if(cmp < 0)
{
// Do the swaps only when needed.
char temp[STR_SIZ];
strcpy(temp,strArr[x]);
strcpy(strArr[x], strArr[j]);
strcpy(strArr[j], temp);
}
}
}
// Verify result
for(int x = 0; x < N; x++) printf("%s\n", strArr[x]);
return 0;
}
I moved your swap into your if check and got rid of your minStr as it was not needed. Notice how I calculate the N size too. Honestly, you were close, but you needed to verify your output.

Why isn't my global allocation structure updating values correctly?

I've been working on a bankers algorithm implementation in C and it seems to work fine except the allocation matrix isn't adding values correctly. In the request resources function, I use a mutex lock at the beginning and unlock right before returning a value to indicate pass or failure. In the function itself, the allocation matrix updates with what's been requested and given but when another thread comes in and does it's request, the allocation resets and starts adding again. I'm not sure why this is since allocation is global like the other structures being modified in the function and they are updating values properly.
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
/* these may be any values >= 0 */
#define NUMBER_OF_CUSTOMERS 5
#define NUMBER_OF_RESOURCES 3
/* the available amount of each resource */
int available[NUMBER_OF_RESOURCES];
/*the maximum demand of each customer */
int maximum[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
/* the amount currently allocated to each customer */
int allocation[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
/* the remaining need of each customer */
int need[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
pthread_mutex_t mutex =
PTHREAD_MUTEX_INITIALIZER;
struct threadParams {
int req[3];
int threadNum;
};
int safe_state(int customer_num){
int work[NUMBER_OF_RESOURCES];
int done =0;
for(int w = 0; w < NUMBER_OF_CUSTOMERS; w++){
work[w] = available[w];
}
int finish[NUMBER_OF_CUSTOMERS];
for(int i = 0; i < NUMBER_OF_CUSTOMERS; i++){
finish[i] = 0;
//setting finish to false
}
for(int k = 0; k < NUMBER_OF_CUSTOMERS; k++){
for(int j = 0; j< NUMBER_OF_RESOURCES; j++){
if(finish[k] == 0 && need[customer_num][k] <= work[j]){
work[j] += allocation[customer_num][j];
finish[k] = 1;
//printf("%d\n", finish[k]);
}
}
}
for(int x = 0; x < NUMBER_OF_CUSTOMERS; x++){
if(finish[x] == 1){
done = 1;
}
else{
done = -1;
}
}
if(done == 1){
printf("\n Granted\n");
return done;
}
printf("\nDenied\n");
return done;
}
void* request_resources(void *arg){
pthread_mutex_lock(&mutex);
struct threadParams *params = arg;
int customer_num = params->threadNum;
printf("\nCustomer %d is in critical\n", customer_num+1);
int request[3];
request[0] = params->req[0];
request[1] = params->req[1];
request[2] = params->req[2];
int pass;
for(int i = 0; i < NUMBER_OF_RESOURCES; i++){
if(request[i] <= need[customer_num][i] && request[i] <= available[i]){
//printf("\nreq: %d, need: %d, avail: %d, alloc: %d\n\t", request[i], need[customer_num][i], available[i],allocation[customer_num][i]);
int state = safe_state(customer_num);
if(state == 1){
available[i] -= request[i];
allocation[customer_num][i] += request[i];
//printf("%d + %d\n", allocation[customer_num][i], request[i]);
need[customer_num][i] -= request[i];
pass = 1;
}
else if(state == -1){
printf("\nThe request from customer %d results in unsafe state\n", customer_num+1);
printf("\nreq: %d, need: %d, avail: %d, alloc: %d\n\t", request[i], need[customer_num][i], available[i],allocation[customer_num][i]);
pass = -1;
break;
}
}
else{
printf("\nreq: %d, need: %d, avail: %d\n", request[i], need[customer_num][i], available[i]);
printf("\nNot enough resources for customer %d's request or the customer doesn't need this resource.\n", customer_num);
pass = -1;
break;
}
printf("\nResource: %d req: %d, need: %d, avail: %d, alloc: %d\n\t",i+1, request[i], need[customer_num][i], available[i],allocation[customer_num][i]);
}
//printf("I'm a thread\n");
pthread_mutex_unlock(&mutex);
printf("\n Customer %d has left critical\n", customer_num+1);
return pass;
}
int release_resources(int customer_num, int release[]){
}
int main(int argc, char *argv[]){
pthread_t threads [NUMBER_OF_CUSTOMERS];
int result;
unsigned index = 0;
// for(int ii = 0; ii < NUMBER_OF_CUSTOMERS; ii++){
// for(int jj = 0; jj < NUMBER_OF_RESOURCES; jj++){
// allocation[ii][jj] += 0;
// }
// }
for(index = 0; index < NUMBER_OF_RESOURCES; index++){
available[index] = strtol(argv[index+1], NULL,10);
}
for(int i = 0; i < NUMBER_OF_CUSTOMERS; i++){
for(int j = 0; j < NUMBER_OF_RESOURCES; j++){
maximum[i][j] = strtol(argv[j+1], NULL, 10)-4;
need[i][j] = 2; //strtol(argv[j+1], NULL, 10) - 6;
//printf("%d\t", maximum[i][j]);
}
}
for(index = 0; index < NUMBER_OF_CUSTOMERS; index++){
printf("\nCreating customer %d\n", index+1);
struct threadParams params;
params.req[0] = 2;
params.req[1] = 2;
params.req[2] = 2;
params.threadNum = index;
result = pthread_create(&threads[index],NULL,request_resources,&params);
}
for(index = 0; index < NUMBER_OF_CUSTOMERS; ++index){
pthread_join(threads[index], NULL);
}
printf("\nDone");
}
After I fixed some issues I got a running version:
#ifdef __cplusplus
#include <cstdio>
#include <cstdlib>
#include <mutex>
#include <thread>
using namespace std;
#else /* (not) __cplusplus */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#endif /* __cplusplus */
/* these may be any values >= 0 */
#define NUMBER_OF_CUSTOMERS 5
#define NUMBER_OF_RESOURCES 3
/* the available amount of each resource */
static int available[NUMBER_OF_RESOURCES];
/*the maximum demand of each customer */
static int maximum[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
/* the amount currently allocated to each customer */
static int allocation[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
/* the remaining need of each customer */
static int need[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
struct ThreadParams {
int req[3];
int threadNum;
};
typedef void* (*PThreadFunc)(void*);
#ifdef __cplusplus
/* multi-threading thin layer for C++ and std::thread */
static mutex mtx;
static inline void lockMutex(mutex *pMtx) { pMtx->lock(); }
static inline void unlockMutex(mutex *pMtx) { pMtx->unlock(); }
typedef std::thread Thread;
static inline int startThread(
Thread *pThread,
void* (*pThreadFunc)(ThreadParams*), ThreadParams *pThreadParams)
{
return (*pThread = Thread(pThreadFunc, pThreadParams)).get_id()
== Thread::id();
/* thread creation failed -> thread id == thread::id() -> 1
* thread creation successful -> thread id != thread::id() -> 0
*/
}
static inline void joinThread(Thread *pThread) { pThread->join(); }
#else /* (not) __cplusplus */
/* multi-threading thin layer for C and pthread */
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static void lockMutex(pthread_mutex_t *pMtx)
{
pthread_mutex_lock(pMtx);
}
static void unlockMutex(pthread_mutex_t *pMtx)
{
pthread_mutex_unlock(pMtx);
}
typedef pthread_t Thread;
static int startThread(
Thread *pThread,
void* (*pThreadFunc)(struct ThreadParams*),
struct ThreadParams *pThreadParams)
{
return pthread_create(pThread, NULL,
(void*(*)(void*))pThreadFunc, pThreadParams);
}
static void joinThread(Thread *pThread) { pthread_join(*pThread, NULL); }
#endif /* __cplusplus */
static int safe_state(int customer_num)
{
int work[NUMBER_OF_RESOURCES];
for (int i = 0; i < NUMBER_OF_RESOURCES; ++i) {
work[i] = available[i];
}
int finish[NUMBER_OF_CUSTOMERS];
for(int i = 0; i < NUMBER_OF_CUSTOMERS; ++i) {
finish[i] = 0;
//setting finish to false
}
for (int k = 0; k < NUMBER_OF_CUSTOMERS; ++k) {
for (int j = 0; j < NUMBER_OF_RESOURCES; ++j) {
if (finish[k] == 0 && need[customer_num][k] <= work[j]) {
work[j] += allocation[customer_num][j];
finish[k] = 1;
//printf("%d\n", finish[k]);
}
}
}
int done = 0;
for (int x = 0; x < NUMBER_OF_CUSTOMERS; ++x) {
done = finish[x] ? 1 : -1;
}
if (done) printf("Granted\n");
else printf("Denied\n");
return done;
}
static void* request_resources(struct ThreadParams *params)
{
lockMutex(&mtx);
int customer_num = params->threadNum;
printf("Customer %d is in critical\n", customer_num+1);
int request[3];
request[0] = params->req[0];
request[1] = params->req[1];
request[2] = params->req[2];
int pass;
for (int i = 0; i < NUMBER_OF_RESOURCES; ++i) {
if (request[i] <= need[customer_num][i] && request[i] <= available[i]) {
//printf("\nreq: %d, need: %d, avail: %d, alloc: %d\n\t", request[i], need[customer_num][i], available[i],allocation[customer_num][i]);
int state = safe_state(customer_num);
if (state == 1) {
available[i] -= request[i];
allocation[customer_num][i] += request[i];
//printf("%d + %d\n", allocation[customer_num][i], request[i]);
need[customer_num][i] -= request[i];
pass = 1;
} else if (state == -1) {
printf("The request from customer %d results in unsafe state\n",
customer_num + 1);
printf("req: %d, need: %d, avail: %d, alloc: %d\n",
request[i], need[customer_num][i], available[i],
allocation[customer_num][i]);
pass = -1;
break;
}
} else {
printf("req: %d, need: %d, avail: %d\n",
request[i], need[customer_num][i], available[i]);
printf("Not enough resources for customer %d's request"
" or the customer doesn't need this resource.\n", customer_num);
pass = -1;
break;
}
printf("Resource: %d req: %d, need: %d, avail: %d, alloc: %d\n",
i + 1, request[i], need[customer_num][i], available[i],
allocation[customer_num][i]);
}
//printf("I'm a thread\n");
printf("Customer %d is about to left critical\n", customer_num + 1);
unlockMutex(&mtx);
return (void*)pass;
}
static int release_resources(int customer_num, int release[]) {
}
int main(int argc, char *argv[])
{
int input[NUMBER_OF_RESOURCES];
/* default input */
for (int i = 0; i < NUMBER_OF_RESOURCES; ++i) input[i] = 10;
/* override default input with command line arguments if provided */
if (argc > NUMBER_OF_RESOURCES) {
for (int i = 0; i < NUMBER_OF_RESOURCES; ++i) {
input[i] = strtol(argv[i + 1], NULL, 10);
}
}
int result;
// for(int ii = 0; ii < NUMBER_OF_CUSTOMERS; ii++){
// for(int jj = 0; jj < NUMBER_OF_RESOURCES; jj++){
// allocation[ii][jj] += 0;
// }
// }
for (int i = 0; i < NUMBER_OF_RESOURCES; ++i) {
available[i] = input[i];
}
for(int i = 0; i < NUMBER_OF_CUSTOMERS; ++i) {
for (int j = 0; j < NUMBER_OF_RESOURCES; ++j) {
maximum[i][j] = input[j] - 4;
need[i][j] = 2; //input[j] - 6;
//printf("%d\t", maximum[i][j]);
}
}
Thread threads[NUMBER_OF_CUSTOMERS];
struct ThreadParams params[NUMBER_OF_CUSTOMERS];
for (int i = 0; i < NUMBER_OF_CUSTOMERS; ++i) {
printf("Creating customer %d\n", i + 1);
params[i].req[0] = 2;
params[i].req[1] = 2;
params[i].req[2] = 2;
params[i].threadNum = i;
result = startThread(threads + i, &request_resources, params + i);
}
for (int i = 0; i < NUMBER_OF_CUSTOMERS; ++i) {
joinThread(threads + i);
}
printf("Done\n");
return 0;
}
Notes:
I was afraid of the life-time of struct threadParams param (in main()). Thus I made it an array and moved its declaration to a scope where it lives longer than the threads. (This was my first recommendation.)
A minor issue: I do not use post-fix inc./dec. if not necessary - a matter of taste.
I introduced some #ifdef __cplusplus and a thin-layer to be able to switch between pthread (C) and std::thread (C++). I did this to be able to compile and debug it in VS2013 with its nice debugger.
A minor issue: I prefixed all globals with static. I did this to prevent any potential issues with externs which might be declared in any header beyond my knowledge.
A minor issue: I provided some default values for missing command line arguments to simplify tests.
The VS2013 debugger uncovered another issue int work[NUMBER_OF_RESOURCES]; (in safe_state(), out of range access) which I fixed.
A minor issue: I re-formatted the output a little bit to make it more compact.
I compiled and tested it in VS2013 on Windows 10 (64 bit) and got this output (usage of std::thread):
Creating customer 1
Customer 1 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 8, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 8, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 8, alloc: 2
Customer 1 is about to left critical
Creating customer 2
Customer 2 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 6, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 6, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 6, alloc: 2
Customer 2 is about to left critical
Creating customer 3
Customer 3 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 4, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 4, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 4, alloc: 2
Customer 3 is about to left critical
Creating customer 4
Customer 4 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 2, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 2, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 2, alloc: 2
Customer 4 is about to left critical
Creating customer 5
Customer 5 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 0, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 0, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 0, alloc: 2
Customer 5 is about to left critical
Done
Drücken Sie eine beliebige Taste . . .
I compiled and tested it also with gcc on cygwin (using pthread):
$ gcc -std=c11 -x c bankers.cc -o bankers -pthread
$ ./bankers
Creating customer 1
Creating customer 2
Customer 1 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 8, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 8, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 8, alloc: 2
Customer 1 is about to left critical
Creating customer 3
Customer 2 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 6, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 6, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 6, alloc: 2
Customer 2 is about to left critical
Creating customer 4
Customer 3 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 4, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 4, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 4, alloc: 2
Customer 3 is about to left critical
Creating customer 5
Customer 4 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 2, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 2, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 2, alloc: 2
Customer 4 is about to left critical
Customer 5 is in critical
Granted
Resource: 1 req: 2, need: 0, avail: 0, alloc: 2
Granted
Resource: 2 req: 2, need: 0, avail: 0, alloc: 2
Granted
Resource: 3 req: 2, need: 0, avail: 0, alloc: 2
Customer 5 is about to left critical
Done
Finally, I found some time to handle this seriously:
I still have problems to understand your implementation in general. (I spent some hours to first understand Edsger Dijkstras Banker's algorithm itself before I came back.)
Thus, I do not understand why you distinguish need[] and threadParams.req[]. When I got it right this should actually be the same (i.e. one of them should not be there).
However, I want to show you what I got so far (which might be a help). After I studied and compared multiple samples I finally made a modified version of Banker's Algorithm on rosettacode.org:
#ifdef __cplusplus
#include <cassert>
#include <cstdio>
#include <cstring>
using namespace std;
#else /* (not) __cplusplus */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#endif /* __cplusplus */
enum { nResources = 4 };
enum { nCustomers = 3 };
struct System {
/* the total amount of resources */
int total[nResources];
/* the available amount of each resource */
int available[nResources];
/* currently allocated resources */
int allocation[nCustomers][nResources];
/* the maximum demand of each customer */
int maximum[nCustomers][nResources];
};
static struct System testSetSafe1 = {
/* the total amount of resources */
{ 6, 5, 7, 6 },
/* the available amount of each resource */
{ },
/* currently allocated resources */
{
{ 1, 2, 2, 1 },
{ 1, 0, 3, 3 },
{ 1, 2, 1, 0 }
},
/* the maximum demand of each customer */
{
{ 3, 3, 2, 2 },
{ 1, 2, 3, 4 },
{ 1, 3, 5, 0 }
}
};
static struct System testSetSafe2 = {
/* the total amount of resources */
{ 6, 5, 7, 6 },
/* the available amount of each resource */
{ },
/* currently allocated resources */
{
{ 1, 0, 0, 1 },
{ 1, 0, 3, 3 },
{ 1, 2, 1, 0 }
},
/* the maximum demand of each customer */
{
{ 5, 3, 2, 2 },
{ 1, 2, 3, 4 },
{ 1, 3, 5, 0 }
}
};
static struct System testSetUnsafe = {
/* the total amount of resources */
{ 6, 5, 7, 6 },
/* the available amount of each resource */
{ },
/* currently allocated resources */
{
{ 1, 2, 2, 1 },
{ 1, 0, 3, 3 },
{ 1, 2, 1, 0 }
},
/* the maximum demand of each customer */
{
{ 5, 3, 2, 2 },
{ 1, 2, 3, 4 },
{ 1, 3, 5, 0 }
}
};
void initSystem(struct System *pSystem)
{
for (int j = 0; j < nResources; ++j) {
pSystem->available[j] = pSystem->total[j];
for (int i = 0; i < nCustomers; ++i) {
pSystem->available[j] -= pSystem->allocation[i][j];
}
}
}
void printR(const char *title, int table[nResources])
{
printf("%s:\n", title);
for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
printf("\n");
for (int j = 0; j < nResources; ++j) printf("\t%d", table[j]);
printf("\n");
}
void printCR(const char *title, int table[nCustomers][nResources])
{
printf("%s:\n", title);
for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
printf("\n");
for (int i = 0; i < nCustomers; ++i) {
printf("C%d", i + 1);
for (int j = 0; j < nResources; ++j) printf("\t%d", table[i][j]);
printf("\n");
}
}
int run(struct System *pSystem)
{
initSystem(pSystem);
printR("Total resources in system", pSystem->total);
printR("Available resources", pSystem->available);
printCR("Customers (currently allocated resources)",
pSystem->allocation);
printCR("Customers (maximum required resources", pSystem->maximum);
int running[nCustomers];
for (int count = nCustomers, safe; count;) {
safe = 0;
for (int i = 0; i < nCustomers; ++i) {
if (running[i]) {
int needed[nResources], blocked = 0;
for (int j = 0, block; j < nResources; ++j) {
needed[j]
= pSystem->maximum[i][j] - pSystem->allocation[i][j];
if ((block = needed[j] > pSystem->available[j])) {
printf("Customer %d blocked due to resource %c\n",
i + 1, 'A' + j);
}
blocked |= block;
}
if (!blocked) {
printf("Customer %d is served.\n", i + 1);
/* allocate resources */
for (int j = 0; j < nResources; ++j) {
pSystem->available[j] -= needed[j];
pSystem->allocation[i][j] += needed[j];
assert(pSystem->allocation[i][j] == pSystem->maximum[i][j]);
}
/* perform customer */
printR("Allocated resources", pSystem->allocation[i]);
running[i] = 0;
printf("Customer %d is done.\n", i + 1);
--count; /* customer finished */
safe = 1; /* processes still safe (no deadlock) */
/* free resources */
for (int j = 0; j < nResources; ++j) {
pSystem->available[j] += pSystem->allocation[i][j];
pSystem->allocation[i][j] = 0;
}
break; /* bail out of inner loop */
}
}
}
if (!safe) {
printf("Unsafe state (i.e. dead lock).\n");
printR("Total resources in system", pSystem->total);
printR("Available resources", pSystem->available);
printCR("Customers (currently allocated resources)",
pSystem->allocation);
printCR("Customers (maximum required resources",
pSystem->maximum);
return -1;
}
printR("Available resources", pSystem->available);
}
return 0;
}
int main()
{
/* 1st try: all requests can be granted soon */
printf(
"1st Run:\n"
"========\n"
"\n");
run(&testSetSafe1);
printf("\n");
/* 2nd try: all requests can be granted by changing order */
printf("2nd Run:\n"
"========\n"
"\n");
run(&testSetSafe2);
printf("\n");
/* 3rd try: unsafe state */
printf("3rd Run:\n"
"========\n"
"\n");
run(&testSetUnsafe);
printf("\n");
/* done */
printf("Done.\n");
return 0;
}
(Debugged in VS2013 but) compiled and tested with gcc in cygwin on Windows 10 (64 bit):
$ gcc -std=c11 -x c bankers.cc -o bankers
$ ./bankers
1st Run:
========
Total resources in system:
A B C D
6 5 7 6
Available resources:
A B C D
3 1 1 2
Customers (currently allocated resources):
A B C D
C1 1 2 2 1
C2 1 0 3 3
C3 1 2 1 0
Customers (maximum required resources:
A B C D
C1 3 3 2 2
C2 1 2 3 4
C3 1 3 5 0
Customer 1 is served.
Allocated resources:
A B C D
3 3 2 2
Customer 1 is done.
Available resources:
A B C D
4 3 3 3
Customer 2 is served.
Allocated resources:
A B C D
1 2 3 4
Customer 2 is done.
Available resources:
A B C D
5 3 6 6
Customer 3 is served.
Allocated resources:
A B C D
1 3 5 0
Customer 3 is done.
Available resources:
A B C D
6 5 7 6
2nd Run:
========
Total resources in system:
A B C D
6 5 7 6
Available resources:
A B C D
3 3 3 2
Customers (currently allocated resources):
A B C D
C1 1 0 0 1
C2 1 0 3 3
C3 1 2 1 0
Customers (maximum required resources:
A B C D
C1 5 3 2 2
C2 1 2 3 4
C3 1 3 5 0
Customer 1 blocked due to resource A
Customer 2 is served.
Allocated resources:
A B C D
1 2 3 4
Customer 2 is done.
Available resources:
A B C D
4 3 6 5
Customer 1 is served.
Allocated resources:
A B C D
5 3 2 2
Customer 1 is done.
Available resources:
A B C D
5 3 6 6
Customer 3 is served.
Allocated resources:
A B C D
1 3 5 0
Customer 3 is done.
Available resources:
A B C D
6 5 7 6
3rd Run:
========
Total resources in system:
A B C D
6 5 7 6
Available resources:
A B C D
3 1 1 2
Customers (currently allocated resources):
A B C D
C1 1 2 2 1
C2 1 0 3 3
C3 1 2 1 0
Customers (maximum required resources:
A B C D
C1 5 3 2 2
C2 1 2 3 4
C3 1 3 5 0
Customer 1 blocked due to resource A
Customer 2 blocked due to resource B
Customer 3 blocked due to resource C
Unsafe state (i.e. dead lock).
Total resources in system:
A B C D
6 5 7 6
Available resources:
A B C D
3 1 1 2
Customers (currently allocated resources):
A B C D
C1 1 2 2 1
C2 1 0 3 3
C3 1 2 1 0
Customers (maximum required resources:
A B C D
C1 5 3 2 2
C2 1 2 3 4
C3 1 3 5 0
Done.
$
This looks quite good (for me).
Now, I made a derived sample introducing multi-threading.
A note about this:
The Wikipedia article Banker's algorithm states that the algorithm is intended for OS resource management like e.g. memory, semaphores and interface access. Sounds for me like, these algorithm is intended to manage things like muteces. Thus, a mutex should/can not be used for it and multi-threading makes not so much sense.
However, let forget about my concern and say this is for educational/understanding purpose:
#ifdef __cplusplus
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <mutex>
#include <thread>
using namespace std;
#else /* (not) __cplusplus */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#endif /* __cplusplus */
enum { nResources = 4 };
enum { nCustomers = 3 };
struct System {
/* the total amount of resources */
int total[nResources];
/* the available amount of each resource */
int available[nResources];
/* currently allocated resources */
int allocation[nCustomers][nResources];
/* the maximum demand of each customer */
int maximum[nCustomers][nResources];
/* customers to serve, blocked customers */
int running, blocked;
};
static struct System testSetSafe1 = {
/* the total amount of resources */
{ 6, 5, 7, 6 },
/* the available amount of each resource */
{ },
/* currently allocated resources */
{
{ 1, 2, 2, 1 },
{ 1, 0, 3, 3 },
{ 1, 2, 1, 0 }
},
/* the maximum demand of each customer */
{
{ 3, 3, 2, 2 },
{ 1, 2, 3, 4 },
{ 1, 3, 5, 0 }
}
};
static struct System testSetSafe2 = {
/* the total amount of resources */
{ 6, 5, 7, 6 },
/* the available amount of each resource */
{ },
/* currently allocated resources */
{
{ 1, 0, 0, 1 },
{ 1, 0, 3, 3 },
{ 1, 2, 1, 0 }
},
/* the maximum demand of each customer */
{
{ 5, 3, 2, 2 },
{ 1, 2, 3, 4 },
{ 1, 3, 5, 0 }
}
};
static struct System testSetUnsafe = {
/* the total amount of resources */
{ 6, 5, 7, 6 },
/* the available amount of each resource */
{ },
/* currently allocated resources */
{
{ 1, 2, 2, 1 },
{ 1, 0, 3, 3 },
{ 1, 2, 1, 0 }
},
/* the maximum demand of each customer */
{
{ 5, 3, 2, 2 },
{ 1, 2, 3, 4 },
{ 1, 3, 5, 0 }
}
};
void initSystem(struct System *pSystem)
{
for (int j = 0; j < nResources; ++j) {
pSystem->available[j] = pSystem->total[j];
for (int i = 0; i < nCustomers; ++i) {
pSystem->available[j] -= pSystem->allocation[i][j];
}
}
pSystem->running = nCustomers; pSystem->blocked = 0;
}
void printR(const char *title, int table[nResources])
{
printf("%s:\n", title);
for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
printf("\n");
for (int j = 0; j < nResources; ++j) printf("\t%d", table[j]);
printf("\n");
}
void printCR(const char *title, int table[nCustomers][nResources])
{
printf("%s:\n", title);
for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
printf("\n");
for (int i = 0; i < nCustomers; ++i) {
printf("C%d", i + 1);
for (int j = 0; j < nResources; ++j) printf("\t%d", table[i][j]);
printf("\n");
}
}
struct Customer {
int i;
struct System *pSystem;
int blocked;
};
static void initCustomer(
struct Customer *pCustomer, int i, struct System *pSystem)
{
pCustomer->i = i;
pCustomer->pSystem = pSystem;
pCustomer->blocked = 0;
}
#ifdef __cplusplus
/* multi-threading thin layer for C++ and std::thread */
static mutex mtx;
static inline void lockMutex(mutex *pMtx) { pMtx->lock(); }
static inline void unlockMutex(mutex *pMtx) { pMtx->unlock(); }
typedef std::thread Thread;
static inline int startThread(
Thread *pThread,
void* (*pThreadFunc)(Customer*), Customer *pCustomer)
{
return (*pThread = Thread(pThreadFunc, pCustomer)).get_id()
== Thread::id();
/* thread creation failed -> thread id == thread::id() -> 1
* thread creation successful -> thread id != thread::id() -> 0
*/
}
static inline void joinThread(Thread *pThread) { pThread->join(); }
#else /* (not) __cplusplus */
/* multi-threading thin layer for C and pthread */
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static void lockMutex(pthread_mutex_t *pMtx)
{
pthread_mutex_lock(pMtx);
}
static void unlockMutex(pthread_mutex_t *pMtx)
{
pthread_mutex_unlock(pMtx);
}
typedef pthread_t Thread;
static int startThread(
Thread *pThread,
void* (*pThreadFunc)(struct Customer*),
struct Customer *pCustomer)
{
return pthread_create(pThread, NULL,
(void*(*)(void*))pThreadFunc, pCustomer);
}
static void joinThread(Thread *pThread) { pthread_join(*pThread, NULL); }
#endif /* __cplusplus */
void* runCustomer(struct Customer *pCustomer)
{
int i = pCustomer->i;
struct System *pSystem = pCustomer->pSystem;
int needed[nResources];
for (int j = 0; j < nResources; ++j) {
needed[j] = pSystem->maximum[i][j] - pSystem->allocation[i][j];
}
for (int done = 0; !done;) {
lockMutex(&mtx); /* thread-safe access to shared system */
if (pCustomer->blocked) --pSystem->blocked;
pCustomer->blocked = 0;
for (int j = 0, block; j < nResources; ++j) {
if ((block = needed[j] > pSystem->available[j])) {
printf("Customer %d blocked due to resource %c\n",
i + 1, 'A' + j);
}
pCustomer->blocked |= block;
}
if (!pCustomer->blocked) {
printf("Customer %d is served.\n", i + 1);
/* allocate resources */
for (int j = 0; j < nResources; ++j) {
pSystem->available[j] -= needed[j];
pSystem->allocation[i][j] += needed[j];
assert(pSystem->allocation[i][j] == pSystem->maximum[i][j]);
}
/* perform customer */
printR("Allocated resources", pSystem->allocation[i]);
--pSystem->running;
done = 1; /* customer finished */
printf("Customer %d is done.\n", i + 1);
/* free resources */
for (int j = 0; j < nResources; ++j) {
pSystem->available[j] += pSystem->allocation[i][j];
pSystem->allocation[i][j] = 0;
}
} else {
++pSystem->blocked;
if ((done = pSystem->running <= pSystem->blocked)) {
printf("Customer %d exited (due to dead-lock).\n", i + 1);
}
}
unlockMutex(&mtx);
}
return 0;
}
int run(struct System *pSystem)
{
initSystem(pSystem);
printR("Total resources in system", pSystem->total);
printR("Available resources", pSystem->available);
printCR("Customers (currently allocated resources)",
pSystem->allocation);
printCR("Customers (maximum required resources", pSystem->maximum);
/* created threads for customers */
lockMutex(&mtx); /* force concurrency a little bit */
Thread threads[nCustomers];
struct Customer customers[nCustomers];
for (int i = 0; i < nCustomers; ++i) {
printf("Creating customer %d\n", i + 1);
initCustomer(customers + i, i, pSystem);
if (startThread(threads + i, &runCustomer, customers + i)) {
printf("ERROR: Failed to start thread for customer %d!\n", i + 1);
}
}
/* unlock mutex to let threads compete */
printf("Ready, steady, go...\n");
unlockMutex(&mtx);
/* join all threads */
for (int i = 0; i < nCustomers; ++i) joinThread(threads + i);
/* report */
if (pSystem->blocked) {
printf("Unsafe state (i.e. dead lock).\n");
printR("Total resources in system", pSystem->total);
printR("Available resources", pSystem->available);
printCR("Customers (currently allocated resources)",
pSystem->allocation);
printCR("Customers (maximum required resources",
pSystem->maximum);
return -1;
}
return 0;
}
int main()
{
/* 1st try: all requests can be granted soon */
printf(
"1st Run:\n"
"========\n"
"\n");
run(&testSetSafe1);
printf("\n");
/* 2nd try: all requests can be granted by changing order */
printf("2nd Run:\n"
"========\n"
"\n");
run(&testSetSafe2);
printf("\n");
/* 3rd try: unsafe state */
printf("3rd Run:\n"
"========\n"
"\n");
run(&testSetUnsafe);
printf("\n");
/* done */
printf("Done.\n");
return 0;
}
(Again debugged in VS2013 but) compiled and tested with gcc in cygwin on Windows 10 (64 bit):
$ gcc -std=c11 -x c bankersMT.cc -o bankersMT -pthread
$ ./bankersMT
1st Run:
========
Total resources in system:
A B C D
6 5 7 6
Available resources:
A B C D
3 1 1 2
Customers (currently allocated resources):
A B C D
C1 1 2 2 1
C2 1 0 3 3
C3 1 2 1 0
Customers (maximum required resources:
A B C D
C1 3 3 2 2
C2 1 2 3 4
C3 1 3 5 0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 is served.
Allocated resources:
A B C D
3 3 2 2
Customer 1 is done.
Customer 2 is served.
Allocated resources:
A B C D
1 2 3 4
Customer 2 is done.
Customer 3 is served.
Allocated resources:
A B C D
1 3 5 0
Customer 3 is done.
2nd Run:
========
Total resources in system:
A B C D
6 5 7 6
Available resources:
A B C D
3 3 3 2
Customers (currently allocated resources):
A B C D
C1 1 0 0 1
C2 1 0 3 3
C3 1 2 1 0
Customers (maximum required resources:
A B C D
C1 5 3 2 2
C2 1 2 3 4
C3 1 3 5 0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 blocked due to resource A
Customer 2 is served.
Allocated resources:
A B C D
1 2 3 4
Customer 2 is done.
Customer 3 is served.
Allocated resources:
A B C D
1 3 5 0
Customer 3 is done.
Customer 1 is served.
Allocated resources:
A B C D
5 3 2 2
Customer 1 is done.
3rd Run:
========
Total resources in system:
A B C D
6 5 7 6
Available resources:
A B C D
3 1 1 2
Customers (currently allocated resources):
A B C D
C1 1 2 2 1
C2 1 0 3 3
C3 1 2 1 0
Customers (maximum required resources:
A B C D
C1 5 3 2 2
C2 1 2 3 4
C3 1 3 5 0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 blocked due to resource A
Customer 2 blocked due to resource B
Customer 3 blocked due to resource C
Customer 3 exited (due to dead-lock).
Customer 1 blocked due to resource A
Customer 1 exited (due to dead-lock).
Customer 2 blocked due to resource B
Customer 2 exited (due to dead-lock).
Unsafe state (i.e. dead lock).
Total resources in system:
A B C D
6 5 7 6
Available resources:
A B C D
3 1 1 2
Customers (currently allocated resources):
A B C D
C1 1 2 2 1
C2 1 0 3 3
C3 1 2 1 0
Customers (maximum required resources:
A B C D
C1 5 3 2 2
C2 1 2 3 4
C3 1 3 5 0
Done.
$
Although, this looks quite good also, I'm not sure about whether the dead-lock detection is 100 % correct. Because multi-threading introduces non-deterministics, this is hard to test. I tried to "debug it by head" but ended up with headache...
Note about implementation:
I used the thin-layer for multi-threading, again. Thus, these samples can be compiled in C++ (std::thread, VS2013/g++) as well as in C (pthread, gcc).

C pattern printing vertical numbers using for loop

I am working on a pattern that prints the following code using for loop
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15
code is as follows, which results in slightly wrong output.
main(){
int i,j,k,n,num;
printf("\n Enter no of rows: ");
scanf("%d",&num);
for(i=1;i<=num;i++,k=num){
for(j=1,n=i;j<=i;j++,n+=k){
printf("%d ",n);
}
printf("\n");
}
}
And the code gives me this .
which is wrong from the output i wanted
1
2 6
3 7 11
4 8 12 16
5 9 13 17 21
The key to this is how you update n in the inner loop. You need it to take into account not just num but also i as you descend through each iteration. I've fixed num at 5 here and placed the assignment to k at the start of the outer loop as this will always be constant:
#include <stdio.h>
int main(void) {
int i, j, k, n, num;
num = 5;
for(i = 1, k = num; i <= num; i++){
for(j = 1, n = i; j <= i; n += k - j, j++){
printf("%d ", n);
}
printf("\n");
}
}
Gives:
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15

Sudoku multiple solutions C

Here is my C sudoku solver using recursive backtracing, with help code from online. The program is small, and branches of the puzzle are stored on the stack and it moves forward adding new puzzle's, and if it fails to find a solution for a position it returns to the previous branch and continues.
While this works for finding 1 solution, I'm trying to adapt it to print every solution. Where the else clause /* SOLUTION FOUND AS NO MORE EMPTY BLOCKS! */ is what ends the function, I've tried returning as sudokuSolver() with various (rows,cols) but can't seem to get to continue correctly to print all solutions.
Code:
#include <stdio.h>
#include <string.h>
int isAvailable(int puzzle[][9], int row, int col, int num)
{
int rowStart = (row/3) * 3;
int colStart = (col/3) * 3;
int i, j;
for(i=0; i<9; ++i) {
if (puzzle[row][i] == num)
return 0;
if (puzzle[i][col] == num)
return 0;
if (puzzle[rowStart + (i%3)][colStart + (i/3)] == num)
return 0;
}
return 1;
}
int solveSudoku(int puzzle[][9], int row, int col)
{
int i;
if (row<9 && col<9) {
if(puzzle[row][col] != 0) {
if ((col+1) < 9)
return solveSudoku(puzzle, row, col+1);
else if ((row+1) < 9)
return solveSudoku(puzzle, row+1, 0);
else /*SOLUTION FOUND AS NO MORE EMPTY BLOCKS!*/
return 1;
}
else {
for(i=0; i<9; ++i) {
if(isAvailable(puzzle, row, col, i+1)) {
puzzle[row][col] = i+1;
if ((col+1) < 9){
if (solveSudoku(puzzle, row, col +1))
return 1;
else
puzzle[row][col] = 0;
}
else if ((row+1) < 9) {
if (solveSudoku(puzzle, row+1, 0))
return 1;
else
puzzle[row][col] = 0;
}
else
return 1;
}
}
}
return 0;
}
else {
return 1;
}
}
int main()
{
int sudoku_arr[9][9] = {
{8,0,0,6,0,0,9,0,5},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,2,0,3,1,0},
{0,0,7,3,1,8,0,6,0},
{2,4,0,0,0,0,0,7,3},
{0,0,0,0,0,0,0,0,0},
{0,0,2,7,9,0,1,0,0},
{5,0,0,0,8,0,0,3,6},
{0,0,3,0,0,0,0,0,0}
};
if (solveSudoku(sudoku_arr, 0, 0)) { //Solve sudoku puzzle
printf("\nSudoku solved:\n");
int row, col;
for(row=0; row<9; row++) {
for(col=0; col<9; col++) {
printf("%d ", sudoku_arr[row][col]);
}
printf("\n");
}
return 0;
}
else {
printf("\nNo sudoku solution");
return -1;
}
}
Now while this solves with the first solution:
Sudoku solved:
8 1 4 6 3 7 9 2 5
3 2 5 1 4 9 6 8 7
7 9 6 8 2 5 3 1 4
9 5 7 3 1 8 4 6 2
2 4 1 9 5 6 8 7 3
6 3 8 2 7 4 5 9 1
4 6 2 7 9 3 1 5 8
5 7 9 4 8 1 2 3 6
1 8 3 5 6 2 7 4 9
There are many other possible solutions i.e.
814637925325149687796825314957318462241956873638274591462793158579481236183562749
814637925325941687796825314957318462241569873638472591462793158579184236183256749
834671925125839647796425318957318462241956873368247591682793154579184236413562789
834671925125839647796524318957318462241956873368247591682793154519482736473165289
834671925125839647796524318957318462241965873368247591682793154519482736473156289
The sudoku_arr is passed by reference. When you set a value inside solveSudoku () function, you are overwriting the original array and hence when it tries to backtrack, there are no more locations with 0 value on array.
What you really want to do is to reset the value to 0 in solveSudoku () before you return 1;.
Also, you would want to print the solution as soon as there are no empty locations left before returning.
This might be helpful.

Scheduling algorithms in C Shortest Remain Time Next

I am working on Shortest Remaining Time Next Scheduling, where I must check every 1 time unit to see if there is another job that has a shorter time remaining left, if equal keep the current process. For the input I use:
PID ArrivalTime Burst/ExecutionTime
1 0 6
2 3 2
3 5 1
4 9 7
5 10 5
6 12 3
7 14 4
8 16 5
9 17 7
10 19 2
and my output: (on the left is what I am getting, the right is what it should be):
PID WAIT TURNAROUND PID WAIT TURNAROUND
1 0 9 1 0 9
2 0 2 2 0 2
3 0 1 3 0 1
4 0 26 4 0 26
5 0 14 5 0 5
6 0 3 6 3 6
7 1 5 7 4 10
8 8 13 8 8 13
9 18 25 9 18 25
10 0 2 10 0 2
Average Wait: 2.7 Ave Turnaround 10.0 Average Wait: 3.3 Average Turnaround 9.9
I have not been able to narrow down where the problem is in the srtn function, All but 3 of my outputs are correct, which is even more confusing! Any help would be appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#define LINELEN 512
#define MAX_PROCESS 100
#define TIME_QUANTUM 1
typedef struct process
{
int ID;
int arrival_time;
int time_to_completion;
double wait_time;
double turn_around;
double time_wait;
int active;
}process;
void fcfs(struct process[MAX_PROCESS], int);
void sjf (struct process[MAX_PROCESS], int);
void srtn(struct process[MAX_PROCESS], int);
void rr (struct process[MAX_PROCESS], int);
void rrc(struct process[MAX_PROCESS], int);
void print_info(struct process[MAX_PROCESS], int);
void sort_by_time(struct process array[MAX_PROCESS], int num_valid_pid);
int main(int ac,char *av[])
{
int counter=0;
int p1=0, p2=0, p3=0;
process array[MAX_PROCESS];
while ( scanf("%d %d %d", &p1, &p2, &p3) != EOF ){//Get all the info available and put it in array of structs
array[counter].ID = p1;
array[counter].arrival_time = p2;
array[counter].time_to_completion = p3;
array[counter].active = 0;
counter++;
}
//fcfs(array, counter);
//sjf (array, counter);
srtn(array, counter);
/*rr (array, counter);
rrc(array, counter);*/
return 0;
}
void srtn(struct process array[MAX_PROCESS], int num_pid){
printf("Shortest Remaining Time Next\n");//for the output so we know what algorithm
//create an array of pids that are valid to search.
int num_valid_processes = 0, current_time=0, i,j, next_process, counter = 0, fin_pid = 0, keep_going=0;//declarations
process to_sort[MAX_PROCESS];
//we want to do this next loop for as many processes as we have, or num_pid
while(keep_going!=1){
//adds all the available processes to the to sort array to be sorted
//available means that it has arrived, which means it is <= current_time
//after it gets all the processes, it breaks out of the for loop
for(i=counter; i<num_pid; i++){
if(array[i].arrival_time<=current_time){
to_sort[num_valid_processes]=array[i];
num_valid_processes++;
counter++;
}
else
break;
}
//sort the to_sort array by the time_to_completion
sort_by_time(to_sort,num_valid_processes);
//set the wait time and turnaround time for the next process
next_process = to_sort[0].ID-1;
if(array[next_process].active==0){//the id hasn't had the wait time calculated yet
array[next_process].wait_time = current_time-array[next_process].arrival_time;
array[next_process].active=1;
array[next_process].time_wait = current_time;
}
if(array[next_process].time_to_completion <= TIME_QUANTUM){
array[next_process].turn_around = array[next_process].wait_time + (current_time-array[next_process].time_wait)+array[next_process].time_to_completion;
fin_pid++;
//delete the process we just worked on so we don't get duplicates.
num_valid_processes--;
for(i=0;i<num_valid_processes;i++){
to_sort[i]=to_sort[i+1];
}
}
else{
array[next_process].time_to_completion = array[next_process].time_to_completion - TIME_QUANTUM;
//to_sort[0].time_to_completion = to_sort[next_process].time_to_completion - TIME_QUANTUM;
}
current_time = current_time+TIME_QUANTUM;
if(fin_pid==num_pid)
keep_going=1;
}
print_info(array, num_pid);
}
void print_info(struct process array[MAX_PROCESS], int num_pid){
int i;
double tot_wait=0, tot_turn = 0;
printf("\x1b[04mPID\tWAIT\tTURNAROUND\n\x1b[24m");
for(i=0; i<num_pid; i++){
printf("%d\t%.0f\t%.0f\n", array[i].ID, array[i].wait_time, array[i].turn_around);
tot_wait=tot_wait+array[i].wait_time;
tot_turn = tot_turn +array[i].turn_around;
}
printf("Average Wait: %.1f Average Turnaround %.1f\n", tot_wait/num_pid, tot_turn/num_pid);
}
void sort_by_time(struct process array[MAX_PROCESS], int num_valid_pid)
{
int i,j;
for (i = 0; i < num_valid_pid; i++)
{
int min = i;
for (j = i+1; j < num_valid_pid; j++){
if (array[j].time_to_completion < array[min].time_to_completion)
min = j;
if (array[j].time_to_completion == array[min].time_to_completion){
if(array[j].ID<array[min].ID)
min = j;
}
}
process temp = array[i];
array[i] = array[min];
array[min] = temp;
}
}
The problem occurs at time 12 -- pid 6 shows up needing 3 seconds and pid 5 is running with 3 seconds left. How do you resolve the tie between processes that need the same remaining time? In favor of pid 6 gives you the result on the left and in favor of pid 5 gives you the result on the right. Given your weak problem definition, either could be correct.

Resources