From f71a1e3618b5f095a5f8421308323f08bda2a5e5 Mon Sep 17 00:00:00 2001 From: Raghavendra Bhat Date: Wed, 13 Jul 2011 18:15:27 +0530 Subject: Custom c programs for locking and multithreaded fops --- c_pgms/locking/dir_open_lock_close.c | 108 ++++++++++ c_pgms/locking/open_lock_close.c | 87 ++++++++ c_pgms/threaded_io/thread_fops.c | 350 +++++++++++++++++++++++++++++++++ c_pgms/threaded_io/thread_read_fstat.h | 57 ++++++ 4 files changed, 602 insertions(+) create mode 100644 c_pgms/locking/dir_open_lock_close.c create mode 100644 c_pgms/locking/open_lock_close.c create mode 100644 c_pgms/threaded_io/thread_fops.c create mode 100644 c_pgms/threaded_io/thread_read_fstat.h (limited to 'c_pgms') diff --git a/c_pgms/locking/dir_open_lock_close.c b/c_pgms/locking/dir_open_lock_close.c new file mode 100644 index 0000000..f7e66aa --- /dev/null +++ b/c_pgms/locking/dir_open_lock_close.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_FILES 31555 + +#ifndef O_DIRECTORY +#define O_DIRECTORY 0200000 +#endif + +int +create_dir (char *name) +{ + int ret = 0; + + ret = mkdir (name, 0755); + if (ret == -1) + fprintf (stderr, "Error: cannot create the directory %s (%s)\n", + name, strerror (errno)); + return ret; +} + +int +open_lock_close (char *name) +{ + int ret = 0; + int fd = -1; + struct flock lock; + char *data = "This is a line"; + + fd = open (name, O_DIRECTORY); + if (fd == -1) { + fprintf (stderr, "Error: cannot open the file %s (%s)\n", name, + strerror (errno)); + return -1; + } + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = 0; + + ret = fcntl (fd, F_SETLK, &lock); + if (ret == -1) + fprintf (stderr, "Error: cannot lock the file %s (%s)\n", name, + strerror (errno)); + + ret = flock (fd, LOCK_SH); + if (ret == -1) + fprintf (stderr, "Error: cannot flock the file %s (%s)\n", name, + strerror (errno)); + + /* ret = write (fd, data, strlen (data)); */ + /* if (ret == -1) */ + /* fprintf (stderr, "Error: cannot write the file %s (%s)\n", name, */ + /* strerror (errno)); */ + + close (fd); + + return ret; +} + +int +delete_file (char *name) +{ + int ret = 0; + + ret = unlink (name); + if (ret < 0) + fprintf (stderr, "Error: Cannot unlink the file %s (%s)\n", + name, strerror (errno)); + + return ret; +} + +int +main () +{ + int ret = 0; + char filename[256] = {0,}; + int i = 0; + + for (i = 1; i <= NUM_FILES ; i++) { + snprintf (filename, sizeof (filename), "file-%d", i); + ret = create_dir (filename); + } + + printf ("Directory creation completed. Proceeding....\n"); + + for (i = 1; i <= NUM_FILES ; i++) { + snprintf (filename, sizeof (filename), "file-%d", i); + open_lock_close (filename); + } + + /* for (i = 1; i <= 100000; i++) { */ + /* snprintf (filename, sizeof (filename), "file-%d", i); */ + /* delete_file (filename); */ + /* } */ + + return 0; +} diff --git a/c_pgms/locking/open_lock_close.c b/c_pgms/locking/open_lock_close.c new file mode 100644 index 0000000..44505d1 --- /dev/null +++ b/c_pgms/locking/open_lock_close.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_FILES 100000 + +void open_lock_close (char *name); +void delete_file (char *name); + +int +main () +{ + int ret = 0; + char filename[256] = {0,}; + int i = 0; + + for (i = 1; i <= NUM_FILES ; i++) { + snprintf (filename, sizeof (filename), "file-%d", i); + open_lock_close (filename); + } + + /* for (i = 1; i <= 100000; i++) { */ + /* snprintf (filename, sizeof (filename), "file-%d", i); */ + /* delete_file (filename); */ + /* } */ + + return 0; +} + +void +open_lock_close (char *name) +{ + int ret = 0; + int fd = -1; + struct flock lock; + char *data = "This is a line"; + + fd = open (name, O_CREAT|O_RDWR, 0644); + if (fd == -1) { + fprintf (stderr, "Error: cannot open the file %s (%s)\n", name, + strerror (errno)); + return; + } + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = 0; + + ret = fcntl (fd, F_SETLK, &lock); + if (ret == -1) + fprintf (stderr, "Error: cannot lock the file %s (%s)\n", name, + strerror (errno)); + + ret = flock (fd, LOCK_SH); + if (ret == -1) + fprintf (stderr, "Error: cannot flock the file %s (%s)\n", name, + strerror (errno)); + + ret = write (fd, data, strlen (data)); + if (ret == -1) + fprintf (stderr, "Error: cannot write the file %s (%s)\n", name, + strerror (errno)); + + close (fd); + + return; +} + +void +delete_file (char *name) +{ + int ret = 0; + + ret = unlink (name); + if (ret < 0) + fprintf (stderr, "Error: Cannot unlink the file %s (%s)\n", + name, strerror (errno)); + + return; +} diff --git a/c_pgms/threaded_io/thread_fops.c b/c_pgms/threaded_io/thread_fops.c new file mode 100644 index 0000000..80947ae --- /dev/null +++ b/c_pgms/threaded_io/thread_fops.c @@ -0,0 +1,350 @@ + +#include "thread_read_fstat.h" + +main() +{ + int ret = -1; + pthread_t thread1, thread2, thread3, thread4, thread5, thread6, thread7; + char *message1 = "Thread 1"; + char *message2 = "Thread 2"; + char *message3 = "Thread 3"; + char *message4 = "Thread 4"; + char *message5 = "Thread 5"; + char *message6 = "Thread 6"; + char *message7 = "Thread 7"; + + int iret1, iret2, iter3, iter4, iter5, iter6, iter7; + + open_t *file = NULL; + file = (open_t *)calloc(1,sizeof(*file)); + if (!file) { + fprintf (stderr, "%s:out of memory\n", + strerror(errno)); + goto out; + } + + file->filename = "thread_file"; + file->flags = O_CREAT | O_RDWR; + file->mode = 0755; + + fstat_t *inode; + inode = (fstat_t *)calloc(1,sizeof(*inode)); + if (!inode) { + fprintf (stderr, "%s:out of memory\n", + strerror(errno)); + goto out; + } + + inode->buf = (struct stat *)calloc(1,sizeof(struct stat)); + if (!inode->buf) { + fprintf (stderr, "%s:Out of memory\n", + strerror(errno)); + goto out; + } + + int fd_main = -1; + + oft *both; + both = (oft *)calloc(1,sizeof(*both)); + if (!both) { + fprintf (stderr, "%s:out of memory\n", + strerror(errno)); + goto out; + } + /* Create independent threads each of which will execute function */ + + both->open = file; + both->fstat = inode; + iret1 = pthread_create (&thread1, NULL, (void *)open_thread, (void *) both); + iret2 = pthread_create (&thread2, NULL, (void *)fstat_thread, (void *) both); + iter3 = pthread_create (&thread3, NULL, (void *)read_thread, (void *)both); + iter4 = pthread_create (&thread4, NULL, (void *)write_truncate_thread, (void *)both); + iter5 = pthread_create (&thread5, NULL, (void *)chown_thread, (void *)both); + iter6 = pthread_create (&thread6, NULL, (void *)write_truncate_thread, (void *)both); + iter7 = pthread_create (&thread7, NULL, (void *)open_lock_close, (void *)both); + + /* Wait till threads are complete before main continues. Unless we */ + /* wait we run the risk of executing an exit which will terminate */ + /* the process and all threads before the threads have completed. */ + + pthread_join( thread1, NULL); + pthread_join( thread2, NULL); + pthread_join( thread3, NULL); + pthread_join( thread4, NULL); + pthread_join( thread5, NULL); + pthread_join( thread6, NULL); + pthread_join( thread7, NULL); + + printf ("%d\n", iret1); + printf ("%d\n", iret2); + printf ("%d\n", iter3); + printf ("%d\n", iter4); + printf ("%d\n", iter5); + printf ("%d\n", iter6); + printf ("%d\n", iter7); + + ret = 0; +out: + if (both) + free(both); + if (inode->buf) + free (inode->buf); + if (inode) + free (inode); + if (file) + free (file); + + return ret; +} + +void +open_lock_close (void *tmp) +{ + oft *all = (oft *)tmp; + open_t *file = NULL; + file = all->open; + fstat_t *inode = NULL; + inode = all->fstat; + int ret = 0; + int fd = -1; + struct flock lock; + char *data = "This is a line"; + + while (1) { + fd = open (file->filename, file->flags, file->mode); + if (fd == -1) { + fprintf (stderr, "%s=>Error: cannot open the file %s " + "(%s)\n", __FUNCTION__, file->filename, + strerror (errno)); + return; + } + + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = 0; + + ret = fcntl (fd, F_SETLK, &lock); + if (ret == -1) + fprintf (stderr, "Error: cannot lock the file %s (%s)\n", + file->filename, strerror (errno)); + + ret = flock (fd, LOCK_SH); + if (ret == -1) + fprintf (stderr, "Error: cannot flock the file %s (%s)\n", + file->filename, strerror (errno)); + + ret = write (fd, data, strlen (data)); + if (ret == -1) + fprintf (stderr, "Error: cannot write the file %s (%s)\n", + file->filename, strerror (errno)); + + lock.l_type = F_UNLCK; + ret = fcntl (fd, F_SETLK, &lock); + if (ret == -1) + fprintf (stderr, "Error: cannot unlock the file %s" + " (%s)\n", file->filename, strerror (errno)); + + ret = flock (fd, LOCK_UN); + if (ret == -1) + fprintf (stderr, "Error: cannot unlock the flock on " + "the file %s (%s)\n", file->filename, + strerror (errno)); + + close (fd); + } + + return; +} + +int +open_thread(void *tmp) +{ + oft *all = (oft *)tmp; + open_t *file = NULL; + file = all->open; + fstat_t *inode = NULL; + inode = all->fstat; + int ret = 0; + int fd = -1; + + while (1) { + if (fd = open (file->filename, file->flags, file->mode) == -1) { + fprintf(stderr, "%s:open error (%s)\n", __FUNCTION__, + strerror(errno)); + ret = -1; + goto out; + } + + close (fd); + } +out: + if (file) + free(file); + return ret; +} + +int +fstat_thread(void *ptr) +{ + oft *all = (oft *)ptr; + fstat_t *inode = NULL; + open_t *file = NULL; + int ret = 0; + int fd = -1; + + file = all->open; + inode = all->fstat; + + fd = open (file->filename, file->flags, file->mode); + if (fd == -1) { + fprintf (stderr, "%s: open error (%s)\n", __FUNCTION__, + strerror (errno)); + ret = -1; + goto out; + } + + while (1) { + if (fstat(fd, inode->buf) == -1) { + fprintf (stderr, "%s:fstat error\n", + strerror(errno)); + ret = -1; + goto out; + } + } + +out: + + close (fd); + if (inode->buf) + free (inode->buf); + if (inode) + free(inode); + return ret; +} + +int +read_thread (void *ptr) +{ + oft *all = NULL; + int fd = -1; + int ret = -1; + fstat_t *stat = NULL; + open_t *file = NULL; + char buffer[4096]; + + all = (oft *)ptr; + stat = all->fstat; + file = all->open; + + open_validate_error_goto(file->filename, file->flags, file->mode); + + while (1) { + ret = read (fd, buffer, 22); + if (ret == -1) { + fprintf (stderr, "%s: read error\n", strerror (errno)); + goto out; + } + + if (ret == EOF) { + lseek (fd, 0, SEEK_SET); + } + } + + ret = 0; +out: + close (fd); + return ret; +} + +int +write_truncate_thread (void *ptr) +{ + oft *all = NULL; + open_t *file = NULL; + fstat_t *stat = NULL; + int fd = -1; + int ret = -1; + char *buffer = "This is a multithreaded environment"; + unsigned int data = 0; + int bytes_written = -1; + + all = (oft *)ptr; + file = all->open; + stat = all->fstat; + + fd = open (file->filename, file->flags | O_APPEND, file->mode); + if (fd == -1) { + fprintf (stderr, "%s: open error (%s)\n", __FUNCTION__, + strerror (errno)); + ret = -1; + goto out; + } + + while (1) { + ret = write (fd, buffer, strlen (buffer)); + bytes_written = ret; + if (ret == -1) { + fprintf (stderr, "%s: write error\n", strerror (errno)); + goto out; + } + + if ((data + bytes_written) >= 4096) { + ret = ftruncate (fd, 0); + if (ret == -1) { + fprintf (stderr, "%s: truncate error\n", + strerror (errno)); + goto out; + } + + data = 0; + } else + data = data + bytes_written; + } + +out: + close (fd); + return ret; +} + +int +chown_thread (void *ptr) +{ + oft *all = NULL; + fstat_t *stat = NULL; + open_t *file = NULL; + int ret = -1; + int fd = -1; + struct stat stat_buf; + + all = (oft *)ptr; + stat = all->fstat; + file = all->open; + + open_validate_error_goto(file->filename, file->flags, file->mode); + + while (1) { + ret = fstat (fd, &stat_buf); + if (ret == -1) { + fprintf (stderr, "%s: fstat error.(%s)", + strerror (errno), __FUNCTION__); + goto out; + } + + if (stat_buf.st_uid == 1315 && stat_buf.st_gid == 1315) + ret = fchown (fd, 2222, 2222); + else + ret = fchown (fd, 1315, 1315); + + if (ret == -1) { + fprintf (stderr, "%s: chown error\n", strerror (errno)); + goto out; + } + } + + ret = 0; +out: + close (fd); + return ret; +} diff --git a/c_pgms/threaded_io/thread_read_fstat.h b/c_pgms/threaded_io/thread_read_fstat.h new file mode 100644 index 0000000..8efc0e9 --- /dev/null +++ b/c_pgms/threaded_io/thread_read_fstat.h @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int open_thread (void *); +int fstat_thread (void *); +int read_thread (void *); +int write_truncate_thread (void *); +int chown_thread (void *); +void open_lock_close (void *); + +int thread1_ret; +int thread2_ret; +int thread3_ret; +int thread4_ret; +int thread5_ret; +int thread6_ret; +int thread7_ret; + +struct open_attributes { + char *filename; + int flags; + mode_t mode; +}; + +typedef struct open_attributes open_t; + +struct fstat_attributes { + int fd; + struct stat *buf; +}; + +typedef struct fstat_attributes fstat_t; + +struct open_fstat { + open_t *open; + fstat_t *fstat; +}; + +typedef struct open_fstat oft; + +#define open_validate_error_goto(filename, flag, mode) do { \ + fd = open (filename, flag, mode); \ + if (fd == -1) { \ + fprintf (stderr, "%s: open error (%s)n", __FUNCTION__, \ + strerror (errno)); \ + ret = -1; \ + goto out; \ + } \ + } while (0); -- cgit