LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-14-2020, 04:04 PM   #1
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,863
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Memory fence in gcc 4.8 (and newer)


Hi, I'm trying to find some portable way to create a memory fence (aka memory barrier) in a multithreaded program that should run on Linux and AIX, compiled with gcc-4.8.x or newer (though it wouldn't hurt if the solution weren't gcc-specific).

Gcc-4.8.x doesn't support C11 stdatomic.h but it has __sync_synchronize

In newer gcc versions there is atomic_thread_fence from stdatomic.h

Also some pthread-functions imply memory fence as a side-effect but I didn't find a standalone 'pthread_msync' (or similar).

Also some other functions (e.g. semop) imply memory fence.

Right now I think it will be some #ifdef-hacking depending on gcc-version, but I would like to hear some better suggestions.

Note: part of the problem is that instead of semaphores/mutexes I use pipes for thread-synchronization/communication as it feels more flexible: for example you cannot wait for two or more semaphores/mutexes in the same time, but you can wait for two or more pipes to become readable with select(2).

Last edited by NevemTeve; 01-14-2020 at 04:08 PM.
 
Old 01-15-2020, 07:58 AM   #2
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
pthread_once synchronizes memory as does pthread_mutex_lock (unless the mutex type is recursive). The POSIX spec talks about it here: https://pubs.opengroup.org/onlinepub...html#tag_04_11.

I know Linux has membarrier but I haven't used it and don't know if AIX would have it - it's been more then 10 yrs since I've worked on AIX.

In the land of speculation - I suppose you might be able to role your own using something like flock and exclusive locking.

-Greg.
 
1 members found this post helpful.
Old 01-19-2020, 02:48 PM   #3
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
Doesn't seem to be much action on this. I like the idea of synchronizing on pipes - I can picture something like erlangs message passing - but it does seem to me you can synchronize on multiple semaphores. Below is a trivial example where on thread waits for events to occur on one thread before signaling a third thread.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

struct wait_args {
	int th_num;
	sem_t* sem;
};

struct post_args {
	int th_num;
	int* n_events;
	sem_t* sem_w;
	sem_t* sem_m;
};

void* wait_function (void* arg) {
	struct wait_args* w = (struct wait_args*)arg;

	sem_wait (w->sem);

	return (void*) &(w->th_num);
}

void* post_function (void* arg) {
	struct post_args* p = (struct post_args*)arg;

	while (1) {
		sem_wait (p->sem_m);

		printf ("post_function %d events\n", *(p->n_events));

		if (*(p->n_events) == 2) {
			break;
		}
	}

	sem_post (p->sem_w);
	
	return (void*) &(p->th_num);
}

void* msg_function (void* arg) {
	struct post_args* p = (struct post_args*)arg;
	for (int i = 1; i < 4; ++i) {
		sleep (1);
		*(p->n_events) = i;
		sem_post (p->sem_m);
	}

	return (void*) &(p->th_num);
}

int main () {
	pthread_t threads[3];

	sem_t sem;
	sem_init (&sem, 0, 0);

	int n_events = 0;
	struct wait_args w = {
		0, &sem
	};

	pthread_create (&threads[0], 0, wait_function, &w);

	sem_t sem2;
	sem_init (&sem2, 0, 0);
	struct post_args p = {
		1, &n_events, &sem, &sem2
	};

	pthread_create (&threads[1], 0, post_function, &p);

	struct post_args m = {
		2, &n_events, &sem, &sem2
	};

	pthread_create (&threads[2], 0, msg_function, &m);

	for (int i = 0; i < 3; ++i) {
		int* response;
		pthread_join (threads[i], (void**)&response);

		printf ("thread %i complete\n", *response);
	}

	return 0;
}
 
Old 01-20-2020, 04:00 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,863

Original Poster
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Hi, eventually I hacked this:
Code:
/* nonstdatomic.h */

#ifndef NONSTDATOMIC_H
#define NONSTDATOMIC_H

#if defined(HAVE_ATOMIC) || __GNUC__ >= 5
    #include <stdatomic.h>
#else
    #define atomic_thread_fence(x) (__sync_synchronize())
#endif

#endif
About waiting for more than one sources: say there is a global request-queue and a worker-thread-specific request-queue (for special usages, e.g.: terminate this thread).

The controller thread usually sends requests to the global queue, but sometimes sends thread-specific requests too.

Now the worker-threads should wait on both request-queues simultaneously.

Last edited by NevemTeve; 01-20-2020 at 04:48 AM.
 
Old 01-21-2020, 07:54 AM   #5
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
Hi, eventually I hacked this:


About waiting for more than one sources: say there is a global request-queue and a worker-thread-specific request-queue (for special usages, e.g.: terminate this thread).

The controller thread usually sends requests to the global queue, but sometimes sends thread-specific requests too.

Now the worker-threads should wait on both request-queues simultaneously.
Terminating the thread can be handled by pthread_cancel of course but it does seem that asking a thread to do something different then normal, and do it now vs, do it the next time you're selected, is outside of the scope of what the pthread synchronization methods were designed for. If it isn't time dependent, such as reset your state before the next run, a flag would handle it.

I think I would be inclined to handle the case where the thread needs to perform a different action on request, with a separate set of threads.
 
  


Reply

Tags
memory fence



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
My mom is 70 and is thinking about going with Linux Mint. She's on the fence. What should I tell her to convince her? JMacSmith Linux - General 10 05-15-2017 03:14 PM
ocfs2 and fence problem Ammad Linux - General 0 08-15-2013 03:44 PM
Red Hat Cluster and fence problem gontolal Red Hat 2 02-02-2010 02:51 PM
[SOLVED] On The Fence About Crossing Over To Linux, Have A Few Concerns And Questions Mulsiphix Linux - Newbie 37 10-19-2009 11:32 AM
LXer: Straddling the Open Source/Proprietary Fence LXer Syndicated Linux News 0 01-03-2007 05:33 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:57 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration