02 May 2016

feedPlanet Maemo

Visitor for Klartext

Felt good about explaining my work last time. For no reason. I guess I'm happy, or I no longer feel PGO's pressure or something. Having to be politically correct all the times, sucks. Making technically and architecturally good solutions is what drives me.

Today I explained the visitor pattern. We want to parse Klartext in such a way that we can present its structure in a editing component. It's the same component for which I utilized a LRU last week. We want to visualize significant lines like tool changes, but also make cycles foldable like SciTe does with source code and a whole lot of other stuff that I can't tell you because of teh secretz. Meanwile these files are, especially when generated using cad-cam software, amazingly huge.

Today I had some success with explaining visitor using the Louvre as that what is "visitable" (the AST) and a Japanese guy who wants to collect state (photos) as a visitor of fine arts. Hoping my good-taste solutions (not my words, it's how Matthias Hasselmann describes my work at Nokia) will once again yield a certain amount of success.

ps. I made sure that all the politically correcting categories are added to this post. So if you'd have filtered away the condescending and controversial posts from my blog, you could have protected yourself from being in total shock now (because I used the sexually tinted word "sucks", earlier). Guess you didn't. Those categories have been in place on my blog's infrastructure since many years. They are like the Körperwelten (Bodyworlds) exhibitions; you don't have to visit them.

0 Add to favourites0 Bury

02 May 2016 8:06pm GMT

Introducing the OGRE fork on GitHub

in this post I want to introduce the OGRE fork on github. The goal of the fork is to provide a stable and reliable OGRE 1.x series while at the same time modernizing parts under the hood updates.

The idea behind this is that there are many existing 1.x codebases, actually a whole 1.x ecosystem, that can be modernized that way.
The last release of the 1.x series was over 2 years ago, so using the current 1.10 branch already gives a lot of improvements.

However the 1.10 branch contains some unnecessary changes that make it incompatible to the 1.9 release. These were reverted, so old code should compile again.

Additionally there are modernizing changes when compared with the upstream at bitbucket, which are discussed in more detail in the following.

Replace legacy renderers

With 1.9 the only stable renderers were GL(2.0) and DX9 which by today are outdated and produce different results than the GLES2 renderer that is used for Web and Mobile, which makes porting applications harder.

Therefore the goal is to get the GL3Plus renderer into a shape where it can act as a drop-in replacement for the old GL render and then drop the latter.

You can see the current status here - while it says that only 41/86 tests pass, most of the failed tests actually only differ in only 1 or 2 pixels which is pretty good when considering we are comparing fixed function vs. dynamically generated shaders (RTSS).

But the fork does not stop here; the GL renderers now also share the context creation code. This allows using the GLES2 renderer on the desktop or creating a GL3+ context using EGL - which is a prerequisite for headless rendering and for running on Wayland/MIR. Overall this makes your applications much more portable.

Improved regression testing

Changing the renderer requires being able to continuously monitor whether the rendering is still correct and to immediately detect regressions.

For this the Testing and VisualTesting frameworks were fixed and now correctly run on Linux and OSX. They run on each pull request to catch errors before the code even touches master.

Furthermore the tests can now be built without input handling (OIS) which hopefully will lead to wider adoption.

The unit tests still use cppunit which is a pain to use when compared to gtest, but changing that would require a large rewrite.

Batteries Included

The build of the fork automatically handles the dependencies by downloading and building them as needed. On all platforms. So you do not have to care about mismatching compile settings any more.

Furthermore the SampleBrowser can now be build without input handling which eases quick testing. And in case you want input, now SDL2 is used instead of the esoteric and outdated OIS.

Next bringing your applications to the web is now easier; OGRE was able to run in the browser for a long time already - but the process was only badly documented. The fork tracks the Emscripten sample code inside the repository and also has documentation on how to use it.

I gave only a high level overview of the changes above. If you need more details, head over here.

A word on OGRE 2.1

You might wonder why one should care about the 1.x and not go for 2.1 directly. The obvious reason is that you have an existing codebase and OGRE 2.1 drastically changes API and even the material file format.

Then, while faster than 1.x, OGRE 2.x is still far from feature completeness with 1.x - it still completely lacks Web and Mobile support.
At this faster also actually depends on your scene/ material usage. For instance, if you only render a single object (product showcase) 2.x will not offer you any advantages.

Finally the main functionality advance in 2.1, namely the new material system (HLMS) and with it physically based shading were backported to 1.x.

Yet if you only care about desktop and want to render large immersive worlds (lots of nodes, lots of materials), 2.1 is the way to go.

0 Add to favourites0 Bury

02 May 2016 2:38pm GMT

29 Apr 2016

feedPlanet Maemo

Putting an LRU in your code

For the ones who didn't find the LRU in Tracker's code (and for the ones who where lazy).

Let's say we will have instances of something called a Statement. Each of those instances is relatively big. But we can recreate them relatively cheap. We will have a huge amount of them. But at any time we only need a handful of them.

The ones that are most recently used are most likely to be needed again soon.

First you make a structure that will hold some administration of the LRU:

typedef struct {
        Statement *head;
        Statement *tail;
        unsigned int size;
        unsigned int max;
} StatementLru;

Then we make the user of a Statement (a view or a model). I'll be using a Map here. You can in Qt for example use QMap for this. Usually I want relatively fast access based on a key. You could also each time loop the stmt_lru to find the instance you want in useStatement based on something in Statement itself. That would rid yourself of the overhead of a map.

class StatementUser
{
        StatementUser();
        ~StatementUser();
        void useStatement(KeyType key);
private:
        StatementLru stmt_lru;
        Map<KeyType, Statement*> stmts;
        StatementFactory stmt_factory;
}

Then we will add to the private fields of the Statement class the members prev and next: We'll make a circular doubly linked list.

class Statement: QObject {
        Q_OBJECT
    ...
private:
        Statement *next;
        Statement *prev;
};

Next we initialize the LRU:

StatementUser::StatementUser() 
{
        stmt_lru.max = 500;
        stmt_lru.size = 0;            
}

Then we implement using the statements

void StatementUser::useStatement(KeyType key)
{
        Statement *stmt;

        if (!stmts.get (key, &stmt)) {

                stmt = stmt_factory.createStatement(key);

                stmts.insert (key, stmt);

                /* So the ring looks a bit like this: *
           *                                    *
           *    .--tail  .--head                *
           *    |        |                      *
           *  [p-n] -> [p-n] -> [p-n] -> [p-n]  *
           *    ^                          |    *
           *    `- [n-p] <- [n-p] <--------'    */

                if (stmt_lru.size >= stmt_lru.max) {
                   Statement *new_head;

          /* We reached max-size of the LRU stmt cache. Destroy current
           * least recently used (stmt_lru.head) and fix the ring. For
           * that we take out the current head, and close the ring.
           * Then we assign head->next as new head. */

                        new_head = stmt_lru.head->next;
                        auto to_del = stmts.find (stmt_lru.head);
                        stmts.remove (to_del);
                        delete stmt_lru.head;
                        stmt_lru.size--;
                        stmt_lru.head = new_head;
                } else {
                        if (stmt_lru.size == 0) {
                                stmt_lru.head = stmt;
                                stmt_lru.tail = stmt;
                        }
                }

        /* Set the current stmt (which is always new here) as the new tail
   * (new most recent used). We insert current stmt between head and
   * current tail, and we set tail to current stmt. */

                stmt_lru.size++;
                stmt->next = stmt_lru.head;
                stmt_lru.head->prev = stmt;

                stmt_lru.tail->next = stmt;
                stmt->prev = stmt_lru.tail;
                stmt_lru.tail = stmt;

        } else {
                if (stmt == stmt_lru.head) {

                /* Current stmt is least recently used, shift head and tail
           * of the ring to efficiently make it most recently used. */

                        stmt_lru.head = stmt_lru.head->next;
                        stmt_lru.tail = stmt_lru.tail->next;
                } else if (stmt != stmt_lru.tail) {

                /* Current statement isn't most recently used, make it most
           * recently used now (less efficient way than above). */

                /* Take stmt out of the list and close the ring */
                        stmt->prev->next = stmt->next;
                        stmt->next->prev = stmt->prev;

                /* Put stmt as tail (most recent used) */
                        stmt->next = stmt_lru.head;
                        stmt_lru.head->prev = stmt;
                        stmt->prev = stmt_lru.tail;
                        stmt_lru.tail->next = stmt;
                        stmt_lru.tail = stmt;
                }

        /* if (stmt == tail), it's already the most recently used in the
   * ring, so in this case we do nothing of course */
        }

        /* Use stmt */

        return;
}

In case StatementUser and Statement form a composition (StatementUser owns Statement, which is what makes most sense), don't forget to delete the instances in the destructor of StatementUser. In the example's case we used heap objects. You can loop the stmt_lru or the map here.

StatementUser::~StatementUser()
{
        Map<KeyType, Statement*>::iterator i;
        for (i = stmts.begin(); i != stmts.end(); ++i) {
                delete i.value();
        }
}

0 Add to favourites0 Bury

29 Apr 2016 9:30pm GMT

27 Apr 2016

feedPlanet Maemo

Secretly reusing my own LRU code

Last week, I secretly reused my own LRU code in the model of the editor of a CNC machine (has truly huge files, needs a statement editor). I rewrote my own code, of course. It's Qt based, not GLib. Wouldn't work in original form anyway. But the same principle. Don't tell Jürg who helped me write that, back then.

Extra points and free beer for people who can find it in Tracker's code.

0 Add to favourites0 Bury

27 Apr 2016 10:55am GMT

23 Mar 2016

feedPlanet Maemo

Q2 2016 Community Council Election Announcement

Dear friends and Maemoans, six months and even a bit more has passed and again it is time to elect a new Community Council for us.

The last election finished on Saturday 13th of September 2015.

The schedule of the voting is as follows:

To get our community to continue strong, we need fresh people with fresh viewpoints to carry on the torch, so please think about volunteering for Maemo Council.

On behalf of the outgoing community council,

Jussi Ohenoja

0 Add to favourites0 Bury

23 Mar 2016 6:17pm GMT

07 Jan 2016

feedPlanet Maemo

2015-12-01 Meeting Minutes

Meeting held 2015-12-01 on FreeNode, channel #maemo-meeting (logs)

Attending: Peter Leinchen (peterleinchen), Halit Bal (HtheB), Gido Griese (Win7Mac), Jussi Ohenoja (juiceme)

Partial: Bernardo Reino (reinob)

Absent:

Summary of topics (ordered by discussion):


(Topic Discussing handling of ex-members accounts):

(Topic Automatic calculation of election results):

(Topic Finalizing the rules for the coding competition):


Action Items:
  • old items:
    • Looking into automatic calculation of election results ...
    • Discuss spam handling with techstaff.
  • new items:
    • Finalize the coding competition rules.
    • Post to TMO announcing the competition and requesting for donations.
    • Discuss competition entries storing with OpenRepos people.

0 Add to favourites0 Bury

07 Jan 2016 11:18am GMT

29 Dec 2015

feedPlanet Maemo

Learning Modern 3D Graphics Programming

one of the best resources to learn modern OpenGL and the one which helped me quite a lot is the Book at www.arcsynthesis.org/gltut/ - or lets better say was. Unfortunately the domain expired so the content is no longer reachable.

Luckily the Book was designed as an open source project and the code to generate the website is still available at Bitbucket. Unfortunately this repository does not seem to be actively maintained any more.

Therefore I set out to make the Book to be available again using Github Pages. You can find the results here:

https://paroj.github.io/gltut/

However I did not simply mirror the pages, but also improved it at several places. So what has changed so far?

hopefully these changes will generate some momentum so this great Book gets extended again. As there were also non-cosmetical changes like the new Chapter I also tagged a 0.3.9 release.

I the process of the above work I found out that there is also a mirror of the original Book at http://alfonse.bitbucket.org/oldtut/. This one is however at the state of the 0.3.8 release, meaning it does not only misses the above changes but also some adjustment happened post 0.3.8 at bitbucket.

1 Add to favourites0 Bury

29 Dec 2015 10:26pm GMT

18 Dec 2015

feedPlanet Maemo

Coding Competition 2016

As you may have already noticed in the recent Meeting Minutes, current Council is about to prepare a Coding Competition (CC) for 2016. In times like these, without Nokia or any other corporate entity sponsoring prizes/devices, there are of course limited resources for big giveaways. Nevertheless we believe the approach is worth it. :) We are relying on your donations.

Looking at last CC's, this time it will probably be more of the supportive kind than rival in the first place. Basically we want to support the ongoing AND future software development in a way that ideally, the winners will get the "right" devices to carry on their efforts or even to the next level (e.g. cross-platform).

Now since no current Councilor has ever arranged a CC, we would like to hear your thoughts on how to get it "right", satisfying community demands (SW) as well as individual developer demands (HW). Please share your ideas! And if you've been involved in organizing recent CC's and are willing to help, please holler. And we sure need help in having an uptodate wiki page.

Furthermore, we are calling all owners of now unused devices to consider donating* them for this CC, respectively to MC e.V., who will be responsible for collecting donations and funds. Especially we are looking at those that got rewarded in recent CC's or device programs (N950 anyone? ;)).

* or selling them for a reasonable price.

The voting webinterface will be the same as for the Maemo Council elections, so jury will be you. We also need you to scrutinize the submitted code (ideally installable/executable + binary). It is undecided yet wether or not to accept closed source apps. As the Council is organizing this CC, it will only intervene if a need occurs. Please help make sure conditions and rules are distinct.

Ideas for categories:

- Old NIT's

- Fremantle

- Harmattan

- Sailfish OS

- "Port it/cross-platform"

- "Maintain it" (packages, CSSU)

- "Update/Fix it"

- "Bugfix it" (known, yet unresolved bugs)

- Core development or "Free it" (backport, clone, replace or supersede closed packages)

- Recent contributions (recent major releases)

- Wishlist (rewarded if/when completed)

- Beginner (first release)

A variant could be to have category "Update/Fix it" for each of the 4 device categories if it can be expected to have enough entries (and prizes).

Ideas and suggestions welcome. :)

1 Add to favourites0 Bury

18 Dec 2015 8:55pm GMT

01 Dec 2015

feedPlanet Maemo

2015-11-24 Meeting Minutes

Meeting held 2015-11-24 on FreeNode, channel #maemo-meeting (logs)

Attending: Peter Leinchen (peterleinchen), Bernardo Reino (reinob), Halit Bal (HtheB), Gido Griese (Win7Mac), Jussi Ohenoja (juiceme)

Partial: Rudiger Schiller (chem|st)

Absent:

Summary of topics (ordered by discussion):


(Topic Council roles reorganization):

(Topic Spam mail through Maemo accounts):

(Topic How to handle user requests to remove projects):

(Topic Code of Conduct):

(Topic Maemo Coding Competition 2015):

(Topic Elections handling and management):


Action Items:
  • old items:
    • The selected Code of Conduct (KDE) still needs to be published on TMO.
    • Looking into automatic calculation of election results ...
    • Arrange Council status on TMO for new Council members
  • new items:
    • Discuss spam handling with techstaff.
    • Finalize the coding competition rules.

1 Add to favourites0 Bury

01 Dec 2015 9:20am GMT

23 Nov 2015

feedPlanet Maemo

IOCTL Android

IOCTL is a very useful system call: it is simple and multiplexes the different commands to the appropriate kernel space function. In this post, I want to describe how you can implement a module with IOCTL support for Android. There are a lot of good articles about it (links below), and I just describe the differences regarding to the Android platform.

So, let's create a very simple misc device and let's play with it, doing some reads and writes. Initially, let's define a very simple kernel module (most of the code was taken from here).

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>


#define MY_MACIG 'G'
#define READ_IOCTL _IOR(MY_MACIG, 0, int)
#define WRITE_IOCTL _IOW(MY_MACIG, 1, int)

static int used;
static char msg[200];

static ssize_t device_read(struct file *filp, char __user *buffer, size_t length, loff_t *offset)
{
return simple_read_from_buffer(buffer, length, offset, msg, 200);
}

static ssize_t device_write(struct file *filp, const char __user *buff, size_t len, loff_t *off)
{
if (len > 199)
return -EINVAL;
copy_from_user(msg, buff, len);
msg[len] = '\0';
return len;
}

static int device_open(struct inode *inode, struct file *file)
{
used++;
return 0;
}

static int device_release(struct inode *inode, struct file *file)
{
used--;
return 0;
}

char buf[200];
int device_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
int len = 200;
switch(cmd) {
case READ_IOCTL:
copy_to_user((char *)arg, buf, 200);
break;

case WRITE_IOCTL:
copy_from_user(buf, (char *)arg, len);
break;

default:
return -ENOTTY;
}
return len;
}

static struct file_operations fops = {
.owner = THIS_MODULE,
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release,
.unlocked_ioctl = device_ioctl
};

static struct miscdevice my_miscdev = {
.name = "my_device",
.mode = S_IRWXUGO,
.fops = &fops,
};

static int __init cdevexample_module_init(void)
{
int ret = misc_register(&my_miscdev);
if (ret < 0) {
printk ("Registering the character device failed\n");
return ret;
}
printk("create node with mknod /dev/my_device\n");
return 0;
}

static void __exit cdevexample_module_exit(void)
{
misc_deregister(&my_miscdev);
}

module_init(cdevexample_module_init);
module_exit(cdevexample_module_exit);
MODULE_LICENSE("GPL");


Compile it and insert into Android kernel.

shell@flounder:/ $ su
shell@flounder:/ $ insmod my_module.ko

Now, we can check the new device in /dev:

shell@flounder:/ $ su
shell@flounder:/ $ ls -l /dev
...
crw-rw---- root mtp 10, 23 2015-11-23 18:04 mtp_usb
crw------- root root 10, 0 2015-11-23 18:11 my_device
crw------- root root 10, 36 2015-11-23 18:04 network_latency
crw------- root root 10, 35 2015-11-23 18:04 network_throughput
crw-rw-rw- root root 1, 3 2015-11-23 18:04 null

...

See that the permissions are limited. Don't forget to set it to:

shell@flounder:/ $ chmod 666 /dev/my_device
shell@flounder:/ $ ls -l /dev
...
crw-rw---- root mtp 10, 23 2015-11-23 18:04 mtp_usb
crw-rw-rw- root root 10, 0 2015-11-23 18:11 my_device
crw------- root root 10, 36 2015-11-23 18:04 network_latency
crw------- root root 10, 35 2015-11-23 18:04 network_throughput
crw-rw-rw- root root 1, 3 2015-11-23 18:04 null

...

Now, let's try to do some operations with our device driver:

shell@flounder:/ $ echo "Hello world" > /dev/my_device
shell@flounder:/ $ cat /dev/my_device

You will see the following error on the logcat:

avc: denied { read write } for name="my_device" dev="tmpfs" scontext=u:r:system_app:s0 tcontext

This means that SELinux (yes, Android makes heavy usage of it) also controls the access to device drivers and you cannot read/write from/to your new drive. You have two options: i) disable SELinux in Android (you need to change some kernel options and rebuild it) or ii) add some new rules into SELinux. Let's do the last to learn a bit more :-)

So, we change the following files and give access (read, write, getattr, ioctl, open and create) to our new device /dev/my_device. If you need to restrict the access, you can adapt the policies according to your needs. For more information about SELinux and Android, take a look in this doc (specially the section "Implementation").

external/sepolicy/device.te
type fscklogs, dev_type;
type full_device, dev_type;
type my_device, dev_type;


external/sepolicy/file_contexts
/dev/rproc_user u:object_r:rpmsg_device:s0
/dev/my_device u:object_r:my_device:s0
/dev/snd(/.*)? u:object_r:audio_device:s0


external/sepolicy/app.te
allow appdomain usb_device:chr_file { read write getattr ioctl };
allow appdomain usbaccessory_device:chr_file { read write getattr };
allow appdomain my_device:chr_file { read write getattr ioctl open create };


Now, let's build the Android framework again and flash the device. Everything should work fine.

shell@flounder:/ $ echo "Hello world" > /dev/my_device
shell@flounder:/ $ cat /dev/my_device
Hello world

That's it!! You can also check the following links


0 Add to favourites0 Bury

23 Nov 2015 6:33pm GMT

17 Nov 2015

feedPlanet Maemo

2015-11-03 Meeting Minutes

Meeting held 2015-11-03 on FreeNode, channel #maemo-meeting (logs)

Attending: Bernardo Reino (reinob), Jussi Ohenoja (juiceme), Peter Leinchen (peterleinchen)

Partial: Rudiger Schiller (chem|st)

Absent: Halit Bal (HtheB), Gido Griese (Win7Mac)

Summary of topics (ordered by discussion):


(Topic TMO forum swearword filter):

(Topic Maemo Coding Competition 2015):


Action Items:
  • old items:
    • The selected Code of Conduct (KDE) still needs to be published on TMO.
    • Looking into automatic calculation of election results ...
  • new items:
    • Arrange Council status on TMO for new Council members

1 Add to favourites0 Bury

17 Nov 2015 6:05pm GMT

11 Nov 2015

feedPlanet Maemo

Latency/Bandwidth and Performance

I've been always interested in scrapping a bit more my application... no matter its level: frontend, framework or native. That's why I guess I have decided to study a bit more Software Systems. Some weeks ago, I was implementing some tests to evaluate my current project in terms of "time spent for certain operations". In addition, I had to force some cache/memory fault, work on some *non* cache-friendly program and, at the end, I was thinking about other aspects of my system. Usually, for software systems, we pretty much focus on latency and bandwidth. For example, when you are developing an application to have an efficient access to memory (cache-friendly!), you are thinking about latency, as you want to avoid (expensive) access to a lower-level memory. Of course, depending on the operation (network, memory access, etc.), latency and bandwidth have a bit different meaning. For example, for network, latency is measured by sending a packet that is returned to the sender. For memory access, latency can be explained as "the delay time between the moment a memory controller tells the memory module to access a particular memory column on a RAM module, and the moment the data from the given array location is available on the module's output pins". [Wiki]

I took a look on some amazing links that gave me a very precise and detailed view about such discussion and here they are:



1 Add to favourites0 Bury

11 Nov 2015 3:43pm GMT

20 Oct 2015

feedPlanet Maemo

2015-09-15 Meeting Minutes

Meeting held 2015-09-15 on FreeNode, channel #maemo-meeting (logs)

Attending: Bernado Reino (reinob), Halit Bal (HtheB), Jussi Ohenoja (juiceme), Peter Leinchen (peterleinchen), Gido Griese (Win7Mac), Rudiger Schiller (chem|st), William McBee (gerbick), Paul Carlin (endsormeans)

Partial:

Absent:

Summary of topics (ordered by discussion):


(Topic Inaugural meeting of the new Maemo Council 2Q/2014):

(Topic Other business):


Action Items:
  • old items:
    • The selected Code of Conduct (KDE) still needs to be published on TMO.
    • Looking into automatic calculation of election results ...
    • Contacting freemangordon and merlin1991 about auto-builder: CSSU-thumb target, GCC versions?
    • Getting maemo trademark registration (everywhere?) renewed (and transferred to MCeV) by the end of February (or within six months since expiry date).
    • Archiving Ovi/Nokia store, especially for Harmattan.
    • Contacting Daphne Won on Facebook and LinkedIn to get administrator rights on Facebook for a Maemo member to migrate the plugin to v2.0 API and maintain it in the future.
  • new items:
    • Arrange user rights for new Council members

1 Add to favourites0 Bury

20 Oct 2015 5:01pm GMT

09 Oct 2015

feedPlanet Maemo

Canon i-Sensys MF8280Cw on 64bit Debian

I've gotten my hands on a Canon i-Sensys MF8280Cw multifunction colour laser printer, in part because I noticed that Canon has published CUPS drivers for Debian (that is Ubuntu), so it should work. It also does work, but I had to jump a few hoops. The driver is available from here (Italian site). Running Debian […]0 Add to favourites0 Bury

09 Oct 2015 3:38pm GMT

13 Sep 2015

feedPlanet Maemo

Meet the new Q2 2015 Maemo Community Council

Dear Maemo community, I have the great honor of introducing the new Community Council for the upcoming Q2/2015 period.

The members of the new council are (in alphabetical order):

The voting results can be seen on the voting page

I want to thank warmly all the members of the community who participated in this most important action of choosing a new council for us!

The new council shall meet on the #maemo-meeting IRC channel next tuesday at 20:00 UTC for the formal handover with the passing council.

Jussi Ohenoja, On behalf of the outgoing Maemo Community Council

1 Add to favourites0 Bury

13 Sep 2015 12:01pm GMT

07 Sep 2015

feedPlanet Maemo

Asynchronous and synchronous I/O in Android NDK

This week, I had some issues on my tests in a Lollipop device with AOSP. I really wanted to have synchronous reads/writes so that I could evaluate my solution in a different way. I am also trying to minimize the effects of caching as much as possible. If you check for async and sync I/O operations for Linux, you'll a lot of references to the flags O_DIRECT, O_SYNC, O_DSYNC, ...

Actually, that's a good way to implement. However, with Android NDK apps, things are not so straightforward.

First, to have a good understanding about the O_*SYNC flags, check this link. Of course, the man page for the command open as well.

First, O_DIRECT does not work in Android since 4.4. See this link for more details about it. That's sad. So, let's try to use the O_*SYNC data.

O_SYNC and O_DSYNC work fine in Android. But, as the description say, only for writes. Another detail: for Android, O_SYNC has the same semantics as O_DSYNC. That's good, but I still want something similar to reads as well.

Why don't we use O_RSYNC? Well, Android does not implement it :-( But it's not the only one... there are other Linux distributions that don't do it either.

What about dropping caches?? See this link for more details. Hum, that works, but after the first read, the data will be cached again :-(

So, I am still looking for a solution for Android Lollipop. Hope to post it soon!


0 Add to favourites0 Bury

07 Sep 2015 9:13am GMT